Хороший вопрос, поэтому upvote, я ожидаю, что использование памяти (Memstorage) такое же, как и у любой другой переменной в .Net. Если вы намереваетесь создать его несколькими способами при вызове, было бы более эффективно создать глобальное распределение памяти. Поскольку Memstorage - это указатель на физический адрес, где хранятся переменные, гораздо лучше перезаписать отдельную переменную внутри нее, а затем создать новое хранилище Memstorage, где ресурсы должны быть повторно объединены и перераспределены.
К счастью, сборщик мусора очень эффективен, и когда вы выйдете из метода, в котором был собран Memstorage, ресурсы, которые он потребовал, будут перераспределены при необходимости или когда ваша программа ничего не делает. Вы всегда можете указать сборщику мусора сделать это вручную, установив для переменной Memstorage значение null и вызвав метод GB.Collect()
, конечно, это зависит от обнуляемого класса Memstorage.
Для обеспечения максимально эффективного распределения памяти следует использовать оператор using
. Это освободит ресурсы, используемые переменной Memstrage. Вот пример, который я конвертировал из opencv, чтобы выполнить то же самое, что и Matlabs bwareopen, в котором меньшие элементы или неожиданные. Это требует работы, но это на стороне подавления данных. Опять же, однако, оператор using
подходит только тогда, когда он не обращается к функции несколько раз, например, внутри цикла.
В конкретном ответе на ваш вопрос вы должны рассмотреть использование оператора using
, чтобы обеспечить правильное освобождение MemStorage, но это должно происходить только в том случае, если метод вызывается с достаточным количеством разрывов. Если этот метод должен вызываться в цикле for последовательно, их MemStorage должен быть объявлен как глобальная переменная внутри класса, а затем, если возможно, обнулен в методе IDisposable класса перед вызовом сборщика мусора. Когда цикл завершен, метод dispose класса может быть вызван для эффективного перераспределения ресурсов. Если вы хотите, чтобы примеры этого также, пожалуйста, дайте мне знать, и я обновлю свой ответ соответственно.
Пример using
и MemStorage:
private Image<Bgr, byte> bwareaopen(Image<Bgr, byte> Input_Image, int threshold)
{
Image<Bgr, byte> bwresults = Input_Image.Copy();
using (MemStorage storage = new MemStorage())
{
for (Contour<Point> contours = Input_Image.Convert<Gray, byte>().FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); contours != null; contours = contours.HNext)
{
Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage);
if (currentContour.Area < threshold)
{
for (int i = currentContour.BoundingRectangle.X; i < currentContour.BoundingRectangle.X + currentContour.BoundingRectangle.Width; i++)
{
for (int j = currentContour.BoundingRectangle.Y; j < currentContour.BoundingRectangle.Y + currentContour.BoundingRectangle.Height; j++)
{
bwresults.Data[j, i, 0] = 0;
bwresults.Data[j, i, 1] = 0;
bwresults.Data[j, i, 2] = 0;
}
}
}
}
}
return bwresults;
}
Код openCV доступен здесь http://tech.groups.yahoo.com/group/OpenCV/message/27345
и вся заслуга М. Клиена за преобразование метода в matlab.
Для тех, кто заинтересован в том, чтобы эта функция работала правильно, для цикла, подавляющего данные, следует использовать граничные ограничения контуров, а не ограничивающий прямоугольник. Как только я настрою это, я обновлю код соответствующим образом.
Надеюсь, это поможет вам немного ответить на вопрос,
Приветствия
Chris