opencv多线程读取视频的问题

来源:互联网 发布:ghost网络克隆软件 编辑:程序博客网 时间:2024/06/06 13:02

想使用多线程对同一个视频进行处理,加快处理速度。首先进行一个最简单的多线程处理的视频的功能:两个线程同时读取视频,并在两个线程中分别显示读取的视频。

首先,为了实现这个功能,我的代码一开始是这样的:

#include <iostream>#include "opencv2/opencv.hpp"#include <Windows.h>using namespace std;using namespace cv;char tmp[]="IMG";LPCWSTR name=(WCHAR *)tmp;HANDLE hMutex = CreateMutex(NULL, false,name);DWORD WINAPI TL_FRAME(LPVOID lpParamter){    WaitForSingleObject(hMutex,INFINITE);    cout<<"Into the sub thread"<<endl;    IplImage* frame=(IplImage*)lpParamter;    cvShowImage("TL",frame);    cvWaitKey(5);    cout<<"leave the sub thread"<<endl;    ReleaseMutex(hMutex);    return 0;}void videoMultiThread(){    CvCapture * cap=cvCreateFileCapture("D:\\JY\\JY_TrainingSamples\\TrafficSignVideo\\trafficSign6.avi");    IplImage * frame;    while(1)    {        WaitForSingleObject(hMutex,INFINITE);        cout<<"Into the main thread"<<endl;        frame=cvQueryFrame(cap);        if(!frame)break;        cvShowImage( "frame",frame);         //MultiThread        HANDLE hThread =    CreateThread(NULL,0,TL_FRAME,frame,0,NULL);        CloseHandle(hThread);        char c=waitKey(5);        if (c==27)break;        cout<<"leave the main thread"<<endl;        ReleaseMutex(hMutex);     }    cvReleaseCapture(&cap);    cvDestroyAllWindows();}int main(){    videoMultiThread();    return 0;}

然后问题出现了。这段代码运行的结果是:只有main线程的视频可以显示,而TL_FRAME线程的视频闪了一下秒退,之后就再也没有出现。但是控制台的输出信息是没有问题得,交替输出:

Into the main thread
leave the main thread
Into the sub thread
leave the sub thread

解决的方法

在主线程创建从线程TL_FRAME之前,添加cvNamedWindow("TL"),同时在从线程TL_FRAME中的图像显示之前,添加cvNamedWindow("TL")。且把线程锁去掉,才可以在两个视频中同时显示图像。

需要注意的是:之前我们显示图像时,喜欢偷懒,直接imshow图像,会自动创建窗口然后图像在上面显示。但是在多线程中会出现问题。必须要在显示之前添加上cvNamedWindow()

使用openMP解决多线程读取问题

使用上述windows的多线程API处理,发现效率不高,CPU占用率很高,速度也不是很快,还会一卡一卡的,尝试使用openMP来解决,发现效果要好多了,CPU占用率下降好多,速度也比上一种方式快,而且使用起来要更加简单。代码如下:

#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/video/background_segm.hpp>#include <opencv2/objdetect/objdetect.hpp>#include <omp.h>//C++#include <iostream>#include <sstream>using namespace cv;using namespace std;int main(int argc, char* argv[]){    //print help information            VideoCapture capture("video.avi");            if(!capture.isOpened()){                //error in opening the video input                cerr << "Unable to open video file: " <<0 << endl;                exit(EXIT_FAILURE);            }            Mat imgGrayScale;            for(;;)            {                bool bSuccess = capture.read(imgGrayScale); // read a new frame from video                if (!bSuccess) //if not success, break loop                {                    cout << "Cannot read the frame from video file" << endl;                    break;                }                //    capture >> imgGrayScale;                Mat img1(imgGrayScale);                Mat img2(imgGrayScale);                #pragma omp parallel sections                {                    #pragma omp section                    {                        Mat img1Gray;                        cvtColor(img1,img1Gray,CV_BGR2GRAY);                        namedWindow("img1Gray");                        imshow("img1Gray",img1Gray);                        waitKey(5);                    }                    #pragma omp section                    {                        Mat img2Gray;                        cvtColor(img1,img2Gray,CV_BGR2GRAY);                        namedWindow("img2Gray");                        imshow("img2Gray",img2Gray);                        waitKey(5);                    }                }            }            waitKey();            getchar();        }
0 0
原创粉丝点击