設定局部區域(ROI),顯示實時畫面
發表作者 Stefan Geißler 日期 2007年4月23日
程序開發人員在C++程式中經常得用到圖像的局部區域(ROI)。 ROI又根據實時畫面的內容而變。日常的技術支持工作讓我認識到,大家對這個區域的認識還有些困惑。因此我編寫了一個小程式,用以演示如何設置ROI參數。
首先檢測ROI幀濾鏡是否在運行:
if( m_pROIFilter.get() ) // Ensure the ROI filter has been loaded. { }
這個對話框為新ROI的左、上、寬、高參數提供了四個輸入。這些變量被分別存入局部變量x, y, w和h中。
為避免輸入值過小, w and h被限制在10以上:
int x,y,w,h; bool bRestartVideo = false; // Get the values from the edit fields x = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIX,NULL,TRUE); y = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIY,NULL,TRUE); w = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIWIDTH,NULL,TRUE); h = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIHEIGHT,NULL,TRUE); // Avoid too small live video if( w < 10 ) w = 10; if( h < 10 ) h = 10;
此外,還需要一個布爾變量bRestartVideo,如改變ROI後現場視頻必須開啟,則將其設為true。
下一步,如正在播放實時畫面,則停止播放。這麼做的原因是輸出視頻格式的尺寸將發生改變,這同樣會影響到IC Imaging Control的圖像緩存大小。
// Check for a running live video. It must be stopped, before the new // ROI can be set. if( m_cGrabber.isDevValid() ) { if( m_cGrabber.isLive() ) { bRestartVideo = true; // Set to true, so the live video will be restarted later. m_cGrabber.stopLive(); } }
然後將新ROI的4個值傳遞給ROI幀濾鏡:
m_pROIFilter->beginParamTransfer(); m_pROIFilter->setParameter("Left",x); m_pROIFilter->setParameter("Top",y); m_pROIFilter->setParameter("Width",w); m_pROIFilter->setParameter("Height",h); m_pROIFilter->endParamTransfer();
如之前正在播放現場視頻,重啟畫面:
// If a live video was running, restart it. if( bRestartVideo ) { m_cGrabber.startLive(); }
下面是源代碼,在一個按鈕事件處理程序中實施:
////////////////////////////////////////////////////////////////////////// // OnBnClickedButtonsetroi // // Set the ROI to the values entered in the fields on the dialog. // void CSampleDlg::OnBnClickedButtonsetroi() { if( m_pROIFilter.get() ) // Ensure the ROI filter has been loaded. { int x,y,w,h; bool bRestartVideo = false; // Get the values from the edit fields x = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIX,NULL,TRUE); y = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIY,NULL,TRUE); w = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIWIDTH,NULL,TRUE); h = ::GetDlgItemInt(this->m_hWnd,IDC_EDITROIHEIGHT,NULL,TRUE); // Avoid too small live video if( w < 10 ) w = 10; if( h < 10 ) h = 10; // Check for a running live video. It must be stopped, before the new // ROI can be set. if( m_cGrabber.isDevValid() ) { if( m_cGrabber.isLive() ) { bRestartVideo = true; m_cGrabber.stopLive(); } } m_pROIFilter->beginParamTransfer(); m_pROIFilter->setParameter("Left",x); m_pROIFilter->setParameter("Top",y); m_pROIFilter->setParameter("Width",w); m_pROIFilter->setParameter("Height",h); m_pROIFilter->endParamTransfer(); // If a live video was running, restart it. if( bRestartVideo ) { m_cGrabber.startLive(); } } }


