为何OpenCV中cvWaitKey(1)延时不是1ms?

我写了一个三帧差分法进行运动目标检测的程序,通过
start = GetTickCount();
if(cvWaitKey(1)>=0) break;
end = GetTickCount();
printf("Diff_time = %ld, \n",end-start);
来获取cvWaitKey(1)的运行时间,发现Diff_time为16,也就是cvWaitKey(1)耗时16ms,这条语句不是应该延时1ms才对吗?求大神帮忙。

源程序如下

#include
#include
#include "highgui.h"
#include

using namespace std;
using namespace cv;

int nFrmNum = 0;//记录帧数

int main(int argc, char* argv[])
{
//变量定义
IplImage* pFrame=NULL;
IplImage* pAfter=NULL;//保存pFrame对应的灰度图像
IplImage *pFrImg1 = NULL;

IplImage *pFrameDiff1 = NULL, *pFrameDiff2 = NULL;
IplImage *pForeImg=NULL;

DWORD start,end;

//要读取的视频文件和保存的视频文件路径
char* openfile="camera1_mov.avi";
//打开视频文件
CvCapture* pCapture=cvCreateFileCapture(openfile);
if(pCapture==NULL) {
    cout<<"video file open error!"<<endl;
    return -1;
}

//创建窗口
cvNamedWindow("video",CV_WINDOW_AUTOSIZE);
cvNamedWindow("source",CV_WINDOW_AUTOSIZE);

//逐帧读取视频并进行处理
while(pFrame = cvQueryFrame( pCapture )){

    nFrmNum++;
    //如果是第一帧,申请内存并进行初始化
    if(nFrmNum==1){
        //原始图像的灰度图
        pAfter=cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1);
        pForeImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1);
        // 原始图像灰度图矩阵
        pFrImg1 = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
        cvSetZero(pFrImg1);
        pFrameDiff1 = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
        cvSetZero(pFrameDiff1);
        pFrameDiff2 = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
    }

    //转化成单通道图像再处理
    cvCvtColor(pFrame, pAfter, CV_BGR2GRAY);
    cvCopy(pFrameDiff1,pFrameDiff2);

cvAbsDiff(pAfter, pFrImg1, pFrameDiff1);
    cvCopy(pAfter, pFrImg1);
    cvThreshold(pFrameDiff1, pFrameDiff1, 20, 255, CV_THRESH_BINARY);
    cvAdd(pFrameDiff1, pFrameDiff2, pForeImg);  //三帧法得运动前景

        cvDilate(pForeImg, pForeImg, 0, 2);
        cvErode(pForeImg, pForeImg, 0, 2);

        cvShowImage("source",pFrame);
        cvShowImage("video",pForeImg);

            start = GetTickCount();

if(cvWaitKey(1)>=0) break;
end = GetTickCount();
printf("Diff_time = %ld, \n",end-start);

}
cvReleaseImage(&pFrame);
cvReleaseImage(&pAfter);
cvDestroyWindow("video");
cvDestroyWindow("source");
return 0;

}

1个回答

cvWaitKey的内部除了sleep休眠之外, 还有重要的Message处理, 比如键盘消息

下面是这个函数的源码:
CV_IMPL int
cvWaitKey( int delay )
{
int time0 = GetTickCount();

for(;;)
{
    CvWindow* window;
    MSG message;
    int is_processed = 0;

    if( (delay > 0 && abs((int)(GetTickCount() - time0)) >= delay) || hg_windows == 0 )
        return -1;

    if( delay <= 0 )
        GetMessage(&message, 0, 0, 0);
    else if( PeekMessage(&message, 0, 0, 0, PM_REMOVE) == FALSE )
    {
        Sleep(1);
        continue;
    }

    for( window = hg_windows; window != 0 && is_processed == 0; window = window->next )
    {
        if( window->hwnd == message.hwnd || window->frame == message.hwnd )
        {
            is_processed = 1;
            switch(message.message)
            {
            case WM_DESTROY:
            case WM_CHAR:
                DispatchMessage(&message);
                return (int)message.wParam;

            case WM_KEYDOWN:
                TranslateMessage(&message);
            default:
                DispatchMessage(&message);
                is_processed = 1;
                break;
            }
        }
    }

    if( !is_processed )
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
}

}

lx624909677
lx624909677 回复jiangchengxuezi: 关键是看你的算法的复杂程度了,也可以在你的循环里只做播放,算法计算放在另外一个线程里来做
5 年多之前 回复
jiangchengxuezi
jiangchengxuezi 显示视频图像的时候必须要加上cvWaitKey();函数,如果没有这个函数图像显示不出来。但是这个函数耗时16ms,如果实时出来视频算法就需要在40ms之内(25帧/s),这也太难了,有什么函数能代替这个函数或怎么样能把这个16ms的延时降下来呢?
5 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐