Как скопировать и обработать WriteableBitmap в отдельном потоке?

В моем приложении kinect есть основной поток, который ответственен за связь между потоком пользовательского интерфейса и другими потоками. Я не могу сделать копию WriteableBitmap, сгенерированную из kinect, и передать это изображение WriteableBitmap в отдельный поток с обработкой EmguCV. Я пробовал все: Clone, CloneCurrentValue, BlockingCollection, но уже были некоторые проблемы, такие как:

Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет

Или обработка данных неверна. Это основной цикл в моем приложении;

WritableBitmap color; WritableBitmap depth; 
while (true) {          
    kinect.updateFrames();                
    ctrlMainWindow.Dispatcher.BeginInvoke(new Action(() =>
    {
       color = kinect.video.getBitmapColor();                   
       depth = kinect.video.getBitmapDepth();
    }));
    updateDetectors(color,depth); // Other thread
 }

1 ответ

Без хорошего, минимального, полного примера кода, который надежно воспроизводит проблему, трудно, если не невозможно, узнать, в чем именно заключается проблема, не говоря уже о том, как ее исправить. Это сказал...

Как вы, наверное, знаете, WriteableBitmap наследуется DispatcherObject, и должен быть доступен только в потоке диспетчера, которому он принадлежит.

Предположительно, призыв к kinect.updateFrames() это то, что на самом деле создает объекты, и поэтому одним из очевидных решений будет вызов этого метода в вызываемом анонимном методе, а не непосредственно перед ним.

Если по какой-либо причине это невозможно, альтернативой может быть замораживание растровых изображений перед попыткой использовать их в неправильном потоке. Например:

kinect.updateFrames();                
color = kinect.video.getBitmapColor();
depth = kinect.video.getBitmapDepth();

color.Freeze();
depth.Freeze();

ctrlMainWindow.Dispatcher.BeginInvoke(new Action(() =>
{
    // use color and depth in other thread
}));

За исключением всего этого, вы можете получить доступ к данным растровых изображений напрямую (например, CopyPixels() или же Lock()/BackBuffer) и использовать эти данные для создания новых растровых изображений в правильном потоке.

Если ничего из вышеперечисленного не окажется полезным для вас, приведите хороший пример кода, как описано в приведенной выше ссылке.

Другие вопросы по тегам