cvWaitKey

来源:互联网 发布:tcp socket编程 编辑:程序博客网 时间:2024/06/05 02:59

http://apps.hi.baidu.com/share/detail/34961575

其实我至今还没有搞清楚这个函数的具体功能是什么,有人说就是等待按键,和Sleep(10) getc(stdin) 的效果是差不多的。

先考虑cvWaitKey的等待作用。

在用摄像头capture vedio的时候,如果在循环里不加入cvWaitKey(1),图像就会显示为一片灰色;

while (img = cvQueryFrame(capture))
   {
      cvShowImage("mainWin",img);
      cvWaitKey(1);
     //Sleep(10);
     //getc(stdin);
   } 

可以做个极端一点的假设:
如果没有cvWaitKey的话, 那么循环里面的每个指令执行时间为0.0000000001s,
总之趋近于0.那么capture可能有10000帧图像, 那么10000帧图像也之需要0.000001s就播放完了, 结果你还没看到画面,
就已经黑屏了 ....

但是! 同样是等待,如果用Sleep(10) getc(stdin) 就无法完成图像的显示,还是一片灰色.

而且,不只是capture vedio的时候会出现这种问题,就连显示单张图片的时候(showimage)也会这样。

这是因为,严格说来cvWaitKey(0)和getc(stdin)不是完全等效的,因为cvWaitKey还要处理窗口之间的消息循环.
以上代码仅仅用Sleep(10)来代替cvWaitKey有问题的原因是sleep之间只是简单等待, 并没有处理消息循环.
因此, sleep还是传统的那种顺序执行的模式. 但是对于窗口程序, 是一种消息驱动的模式, 可以简单的
看作是一种多线程的程序, 内部还有一个机制来处理窗口的显示.

Reference:

//cvWaitKey源代码:

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);
        }
    }
}


原创粉丝点击