Поэтому между одним захватом данных мне приходится копировать массив и, если возможно, сохранять его, чтобы освободить вспомнить этот образ. Важно не потерять ни одного изображения с камеры, даже если для этого придется увеличить используемую память: вполне допустимо, что потребитель (сохранение изображений с освобождением памяти) работает медленнее, чем производитель; однако недопустимо не скопировать изображение в память вовремя.
Я написал пример кода, который должен имитировать проблему:
- : изображение, созданное камерой, которое необходимо скопировать в BlockingCollection до поступления следующего изображения
Код: Выделить всё
image_ushort
- : имеет цикл, который должен имитировать поступление изображения каждый раз_wait; за это время производитель должен скопировать изображение в BlockingCollection.
Код: Выделить всё
producerTask
- : должен работать с BlockingCollection, сохраняя изображения на диск и тем самым освобождая память; не имеет значения, работает ли потребитель медленнее, чем производитель.
Код: Выделить всё
consumerTask
Вот мой код:
Код: Выделить всё
private void Execute_test_producer_consumer1()
{
//Images are stored as ushort array, so we create a BlockingCollection
//to keep images when they arrive from camera
BlockingCollection imglist = new BlockingCollection();
string lod_date = "";
/*producerTask simulates a camera that returns an image every time_wait
milliseconds. The image is copied and inserted in the BlockingCollection
to be then saved on disk in the consumerTask*/
Task producerTask = Task.Factory.StartNew(() =>
{
//Number of images to process
int num_img = 3000;
//Time between one image and the next
long time_wait = 1;
//Time log variables
var watch1 = System.Diagnostics.Stopwatch.StartNew();
long watch_log = 0;
long delta_time = 0;
long timer1 = 0;
List timer_delta_log = new List();
List timer_delta_log_time = new List();
int ii = 0;
Console.WriteLine("-----START producer");
watch1.Restart();
//Here I expect every wait_time (or a little more) an image will be inserted
//into imglist
while (ii < num_img)
{
timer1 = watch1.ElapsedMilliseconds;
delta_time = timer1 - watch_log;
if (delta_time >= time_wait || ii == 0)
{
//Add image
imglist.Add((ushort[])image_ushort.Clone());
//Inserting data for time log
timer_delta_log.Add(delta_time);
timer_delta_log_time.Add(timer1);
watch_log = timer1;
ii++;
}
}
imglist.CompleteAdding();
watch1.Stop();
lod_date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
Console.WriteLine("-----END producer: " + lod_date);
// We only print images that are not inserted on schedule
int gg = 0;
foreach (long timer_delta_log_t in timer_delta_log)
{
if (timer_delta_log_t > time_wait)
{
Console.WriteLine("-- Image " + (gg + 1) + ", delta: "
+ timer_delta_log_t + ", time: " + timer_delta_log_time[gg]);
}
gg++;
}
});
Task consumerTask = Task.Factory.StartNew(() =>
{
string file_name = "";
int yy = 0;
// saving images and removing data
foreach (ushort[] imm in imglist.GetConsumingEnumerable())
{
file_name = @"output/" + yy + ".png";
Mat image1 = new Mat(row, col, MatType.CV_16UC1, imm);
//By commenting on this line, the timing of the producer is respected
image1.ImWrite(file_name);
image1.Dispose();
yy++;
}
imglist.Dispose();
lod_date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
Console.WriteLine("-----END consumer: " + lod_date);
});
}
Код: Выделить всё
while(!imglist.IsCompleted)
{
ushort[] elem = imglist.Take();
file_name = @"output/" + yy + ".png";
Mat image1 = new Mat(row, col, MatType.CV_16UC1, elem);
//By commenting on this line, the timing of the producer is respected
image1.ImWrite(file_name);
image1.Dispose();
yy++;
}
Что я делаю не так?
Подробнее здесь: https://stackoverflow.com/questions/709 ... collection