Tôi chụp ảnh từ webcam, thực hiện xử lý nặng trên chúng, sau đó hiển thị kết quả. Để giữ tốc độ khung hình cao, tôi muốn xử lý các khung khác nhau chạy song song.tạo phẩm xử lý hình ảnh song song
Vì vậy, tôi có một 'Nhà sản xuất', chụp hình ảnh và thêm chúng vào 'inQueue'; cũng phải mất một hình ảnh từ 'outQueue' và hiển thị nó:
public class Producer
{
Capture capture;
Queue<Image<Bgr, Byte>> inQueue;
Queue<Image<Bgr, Byte>> outQueue;
Object lockObject;
Emgu.CV.UI.ImageBox screen;
public int frameCounter = 0;
public Producer(Emgu.CV.UI.ImageBox screen, Capture capture, Queue<Image<Bgr, Byte>> inQueue, Queue<Image<Bgr, Byte>> 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++;
}
}
}
Có khác nhau 'Người tiêu dùng' người có một hình ảnh từ inQueue, làm một số chế biến, và thêm chúng vào outQueue:
public class Consumer
{
Queue<Image<Bgr, Byte>> inQueue;
Queue<Image<Bgr, Byte>> outQueue;
Object lockObject;
string name;
Image<Bgr, Byte> image;
public Consumer(Queue<Image<Bgr, Byte>> inQueue, Queue<Image<Bgr, Byte>> 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);
}
}
}
}
phần còn lại của các mã quan trọng là phần này:
private void Form1_Load(object sender, EventArgs e)
{
Consumer[] c = new Consumer[consumerCount];
Thread[] t = new Thread[consumerCount];
Object lockObj = new object();
Queue<Image<Bgr, Byte>> inQueue = new Queue<Image<Bgr, Byte>>();
Queue<Image<Bgr, Byte>> outQueue = new Queue<Image<Bgr, Byte>>();
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();
}
các parallelisation thực sự hoạt động tốt, tôi có được một sự gia tăng tốc độ thẳng với mỗi chủ đề gia tăng (lên đến một điểm nhất định tất nhiên). Vấn đề là tôi nhận được đồ tạo tác ở đầu ra, ngay cả khi chỉ chạy một luồng. Các đồ tạo tác trông giống như một phần của bức tranh không ở đúng nơi.
Bất kỳ ý tưởng nào gây ra điều này? Cảm ơn
Đó là thứ mà trò chơi cũ được tạo ra như thế nào. Về cơ bản, bạn đang cố gắng trộn lẫn các khái niệm kỹ thuật cũ với các khái niệm mới. Và đó là lý do tại sao nó không thực sự hiệu quả. Bạn cần sử dụng nhiều Threads (những gì bạn đã làm). Tôi không thực sự là nhà phát triển trò chơi, nhưng tôi nghĩ bạn không nên sử dụng EventQue hoặc bất kỳ khóa Màn hình nào. Bạn có thể chỉ đơn giản là overdraw hình ảnh mà không nhận được deadlocks. Nhưng tôi không chắc chắn về nó. Vì vậy, tôi đã không đăng bất cứ điều gì, gây ra không chính xác biết giải pháp. Nhưng tôi nghĩ bạn nên suy nghĩ về đề xuất giải pháp của tôi. – alpham8