المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : Artefacts in parallel image processing



C# Programming
07-23-2012, 03:55 PM
I capture images from a webcam, do some heavy processing on them, and then show the result. To keep the framerate high, i want to have the processing of different frames run in parallel.

So, I have a 'Producer', which captures the images and adds these to the 'inQueue'; also it takes an image from the 'outQueue' and displays it:
public class Producer { Capture capture; Queue inQueue; Queue outQueue; Object lockObject; Emgu.CV.UI.ImageBox screen; public int frameCounter = 0; public Producer(Emgu.CV.UI.ImageBox screen, Capture capture, Queue inQueue, Queue outQueue, Object lockObject) { this.screen = screen; this.capture = capture; this.inQueue = inQueue; this.outQueue = outQueue; this.lockObject = lockObject; } public void produce() { while (true) { lock (lockObject) { inQueue.Enqueue(capture.QueryFrame()); if (inQueue.Count == 1) { Monitor.PulseAll(lockObject); } if (outQueue.Count > 0) { screen.Image = outQueue.Dequeue(); } } frameCounter++; } } }
There are different 'Consumers' who take an image from the inQueue, do some processing, and add them to the outQueue:
public class Consumer { Queue inQueue; Queue outQueue; Object lockObject; string name; Image image; public Consumer(Queue inQueue, Queue outQueue, Object lockObject, string name) { this.inQueue = inQueue; this.outQueue = outQueue; this.lockObject = lockObject; this.name = name; } public void consume() { while (true) { lock (lockObject) { if (inQueue.Count == 0) { Monitor.Wait(lockObject); continue; } image = inQueue.Dequeue(); } // Do some heavy processing with the image lock (lockObject) { outQueue.Enqueue(image); } } } }
Rest of the important code is this section:
private void Form1_Load(object sender, EventArgs e) { Consumer[] c = new Consumer[consumerCount]; Thread[] t = new Thread[consumerCount]; Object lockObj = new object(); Queue inQueue = new Queue(); Queue outQueue = new Queue(); p = new Producer(screen1, capture, inQueue, outQueue, lockObj); for (int i = 0; i < consumerCount; i++) { c[i] = new Consumer(inQueue, outQueue, lockObj, "c_" + Convert.ToString(i)); } for (int i = 0; i < consumerCount; i++) { t[i] = new Thread(c[i].consume); t[i].Start(); } Thread pt = new Thread(p.produce); pt.Start(); }
The parallelisation actually works fine, I do get a linear speed increase with each added thread (up to a certain point of course). The problem is that I get artifacts in the output, even if running only one thread. The artifacts look like part of the picture is not in the right place.


Example of the artifact (this is without any processing to keep it clear, but the effect is the same) (http://i47.tinypic.com/rm1udf.jpg)

Any ideas what causes this?
Thanks