cvWaitKey的问题

在win32下缺少cvwaitkey时会造成显示视频或图片时不正常,通常是显示全灰色的窗口,而在MFC中显示图片则不用cvwaitkey,因为MFC有自己的消息循环机制。

问题:    1、cvWaitKey中影响显示的关键步骤是?

cvwaitkey源码:

CV_IMPL int

cvWaitKey( int delay)

{

    int time0=GetTickCount();

    for(;;)

   {

       CvWindow* window;

       MSG message;

        intis_processed= 0;

 

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

            return-1;

        if(delay<= 0 )

           GetMessage(&message, 0, 0, 0);//GetMessage从消息队列中取出一条消息

        else if(PeekMessage(&message, 0, 0, 0, PM_REMOVE) ==FALSE )//获取当前调用的线程的所有消息

// PeekMesssge只得到那些与参数hWnd标识的窗口相联系的消息或被lsChild确定为其子窗口相联系的消息,并且该消息要在由参数wMsgFiterMin和wMsgFiherMax确定的范围内。如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。如果hWnd为-1,PeekMessage只返回hWnd值为NULL的消息,该消息由函数PostThreadMessage寄送。如果wMsgFilterMin和wMsgFilterMax都为零,PeekMessage返回所有可得的消息(即,无范围过滤)。

       {

           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_SYSKEYDOWN:

                    if(message.wParam== VK_F10 )

                   {

                       is_processed = 1;

                        return (int)(message.wParam<<16);

                   }

                    break;

                case WM_KEYDOWN:

                   TranslateMessage(&message);

                   if((message.wParam>= VK_F1 && message.wParam <= VK_F24) ||

                     message.wParam == VK_HOME||message.wParam == VK_END ||

                     message.wParam == VK_UP|| message.wParam == VK_DOWN ||

                     message.wParam == VK_LEFT || message.wParam== VK_RIGHT ||

                     message.wParam ==VK_INSERT || message.wParam == VK_DELETE ||

                     message.wParam ==VK_PRIOR || message.wParam == VK_NEXT )

                   {

                       DispatchMessage(&message);//DispatchMessage(&msg)把你的message传给wndproc这个函数并且运行这个函数

                       is_processed = 1;

                        return (int)(message.wParam<<16);

                   }

                default:

                   DispatchMessage(&message);

                   is_processed = 1;

                    break;

               }

           }

       }

        if(!is_processed)

       {

           TranslateMessage(&message);

           DispatchMessage(&message);

       }

   }

}

分析源码可知:

1:当 cvwaitkey参数为0时,有WM_KEYDOWN、WM_SYSKEYDOWN、WM_DESTROY、WM_CHAR消息时结束等待,否则持续循环

2:当 cvwaitkey参数大于0时,有WM_KEYDOWN、WM_SYSKEYDOWN、WM_DESTROY、WM_CHAR消息或等到时间大于delay时 结束等待,否则持续循环

3:

调用opencvc显示图片或一帧视频需三步:

         1)cvNameWindow

         2)cvShowImage

         3)cvwaitkey

         创建的窗口的指针保存在hg_windowsz中

4:cvWaitKey中影响显示的关键步骤是DispatchMessage函数,

用以下代码代替cvWaitKey时,在win32中能正确显示图片

MSGmessage;

while(1)

{

         GetMessage(&message,0,0,0);

         DispatchMessage(&message);       }

 

cvWaitKey与多线程

cvwaitkey会调用DispatchMessage函数,所以在多线程时,尽量不要把cvWaitKey放到临界区里。

因为如果界面线程进入临界区后,收到了某消息(比如退出消息),那么会在DispatchMessage这里转去响应收到的消息,直到处理完毕才返回。

而此时还并没有退出临界区,因此有可能造成另一线程无法进入临界区从而被阻塞,

万一界面线程(在响应退出消息时)又需要等待被阻塞的线程(等它先退出然后再做些收尾工作),这样就形成死锁了

 

不清楚的问题:
 

1:MFC中关于opencv窗口的DispatchMessage函数在哪里调用?

2:循环过程中刷新窗口的过程是怎样的?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值