(轉)關於cvShowImage()和cvWaitKey()千絲萬縷關係之我遇

由於項目需要,近期一直在做基於攝像機方面的研究,前幾天寫了一個小程序,要實時顯示攝像機捕捉到的圖像,本來以爲是一件很簡單的事情,卻讓我費了不少功夫,也學到了不少東西。攝像機都有自己的SDK,截取部分有自己的API,我所要做的就是把攝像機截取到的圖像格式(yuv422)轉換到我顯示所需要的rgb格式(這個我近期會抽時間研究下,然後寫點東西),然後通過調用OpenCV函數來顯示就可以了,但我遇到的問題卻是一個又一個。
      在創建完OpenCV所支持的圖像數據結構IplImage後,需要把轉換後的rgb格式複製到IplImage數據結構中,在複製的過程中,我把行列順序弄反,結果後來得到的圖像是花屏。另外一個比較有意思的事情是關於OpenCV函數cvShowImage()和cvWaitKey(),之前都是用這兩個函數顯示一幅圖像,從來沒有做過連續顯示(視頻顯示)的工作,當我確認我的IplImage是千真萬確正確後,我用cvShowImage()函數顯示卻得到了一幅灰色圖像,而且鼠標顯示一直處於忙碌狀態,因爲我要用while(1)循環一直調用cvShowImage()函數,我當時把cvWaitKey()函數放在了while循環外面,抱着試試看的態度我把cvWaitKey()函數放在循環內部cvShowImage()的後面,圖像就可以正常顯示了,google下,原來有人遇到和我一樣的問題:http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=3324&p=11520,看了上面的解釋,自己還是有些不明白,主要是對Windows編程瞭解很少,裏面關於消息處理機制的東西不太明白。
      爲了方便讀者看,把Windows平臺下的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, 000);
        
else if( PeekMessage(&message, 000, 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);
        }
    }
}


關於cvWaitKey()函數的說明:

函數原型:int cvWaitKey( int delay=0 );
The cvWaitKey() function asks the program to stop and wait for a keystroke.
If a positive argument is given, the program will wait for that number of milliseconds and then continue even if nothing is pressed.
If the argument is set to 0 or to a negative number, the program will wait indefinitely for a keypress.
鑑於以上幾點:
我現在的處理方法是:把cvWaitKey()函數放在循環內部cvShowImage()的後面,參數選1,1ms的時間還是可以忽略不計的。這樣就可以實時的顯示攝像機圖像了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章