在线程之间解析 OpenCV 帧

Posted

技术标签:

【中文标题】在线程之间解析 OpenCV 帧【英文标题】:parse OpenCV frame between threads 【发布时间】:2015-02-24 11:22:41 【问题描述】:

嘿,我在 Windows 上有一个简单的线程:

while (!MainThreadHasFinished) 
    cv::Mat frame = (cv::Mat)lpParameter;       //Casting try.
    cv::imshow("Camera image", (frame));        //Show Img in window
    printf("img printed");                      //print text to cmd

    if (cv::waitKey(1) == 27)                   // exit this loop when ESC was pressed
        break;
    
    return 0;

问题在于我无法做到cv::imshow,这似乎不是对 cv::Mat 的强制转换 :)

我将线程创建为:

DWORD thread_ID;
HANDLE handle_NumberCruncher = CreateThread( 
    NULL,                   // default security attributes
    0,                      // use default stack size  
    NumberCruncher,         // thread function name
    &frame,                 // argument to thread function 
    0,                      // use default creation flags 
    &thread_ID);            // returns the thread identifier 

我在 MSDN 和 Stack 上看到过多个关于投射的参考,但没有关于图像的内容。

如果这是不可能的,那么一般的问题是如何在线程之间解析数据。想法是可以在主线程中对图像进行一些处理,然后将其解析为不是每个图像都需要的一些更高级的东西。不使用全局变量。因为线程可能在不同的处理器上,就像一个例子:)

【问题讨论】:

线程没有锁 - 唷。 【参考方案1】:

lpParameter 是一个void* 指针。您必须先将其转换为 cv::Mat 指针类型,即:

DWORD WINAPI NumberCruncher( LPVOID lpParameter )

   while (!MainThreadHasFinished) 
      cv::Mat* frame = (cv::Mat*)lpParameter;     //Casting try.
      printf("img printed");                      //print text to cmd

      // Display image in the main thread
      // ...

      Sleep(1);
   
   return 0;


DWORD thread_ID;
HANDLE handle_NumberCruncher = CreateThread( 
    NULL,                   // default security attributes
    0,                      // use default stack size  
    NumberCruncher,         // thread function name
    &frame,                 // argument to thread function 
    0,                      // use default creation flags 
    &thread_ID);            // returns the thread identifier 

或者,如果线程不需要访问原始变量:

cv::Mat value = *(cv::Mat*)lpParameter;


附言: GUI 系统通常允许您在屏幕上显示内容并在主线程上获取用户输入。尝试在主线程中使用imshow & waitkey

【讨论】:

啊该死的,我尝试了您的建议,但收到以下错误:opencvTest.exe 中 0x7648C42D 处的未处理异常:Microsoft C++ 异常:内存位置 0x0588FAF4 处的 cv::Exception。它在cv::imshow 被调用时出现 GUI 系统通常允许您在屏幕上显示内容并在主线程上获取用户输入。尝试只使用主线程中的imshowwaitKey 效果很好。我测试了你关于主线程应该有 GUI 应用程序的概念。但我可以做到cv::Mat output = cv::Mat::zeros(120, 350, CV_8UC3); putText(output, "Hello World :)", cvPoint(15, 70), cv::FONT_HERSHEY_PLAIN, 3, cvScalar(0, 255, 0), 4); imshow("Output", output);,这意味着如果frame 被正确传递或者? imshow 不是线程安全的,因此请在同步后立即执行。此外,您可能需要在使用cv::namedWindow("Output") 创建线程之前初始化可视化窗口。

以上是关于在线程之间解析 OpenCV 帧的主要内容,如果未能解决你的问题,请参考以下文章

Opencv/c++ - 在线程中录制实时视频,在另一个线程中处理图像?

OpenCV 和 Python 多线程 - 在 VideoCapture 对象中搜索

用 C++ 将 OpenCV 帧写入磁盘:单线程写入速度是不是受磁盘吞吐量以外的任何限制?

OpenCV VideoCapture解析

多线程 OpenCV 程序

在多线程应用程序中使用 opencv waitKey()