opencv多线程读取视频的问题

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

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

#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();
        }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值