(注:第一種方法是個人原創 ^_^。 第二種方法是從網上學習的。)ide
第一種方法:利用 板卡的API: GetJpegImage 獲得 Jpeg 格式的圖像數據,而後用opencv裏的一個函數進行解碼,獲得IplImage對象。(我很鬱悶海康威視採集卡爲何不直接提供RGB圖像數據,而是提供了一個Jpeg數據給用戶。)函數
libjpeg庫就是專門處理 jpeg 格式的圖像數據的,包括解碼縮jpeg 格式的圖像等。學習
opencv的庫依賴於libjpeg庫。我看了libjpeg庫的源代碼,而後又看了opencv 裏 cvLoadImage這部分的源代碼,發現opencv已經封裝好了一個圖像解碼器: cvImageDecoder.ui
並且opencv的API 還提供了一個解碼 內存中的圖像數據的函數:spa
CVAPI(IplImage*) cvDecodeImage( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));code
先生成CvMat*,而後直接調用 cvDecodeImage 便可,如下是部分源代碼:視頻
1 void testCardAPI() 2 { 3 HANDLE channelHandle ; 4 DWORD nport; 5 6 //initialize the card 7 8 SetDefaultVideoStandard(StandardPAL); //returns 0 if error 9 10 //返回通道個數 11 int nChannels = InitDSPs(); 12 13 if( nChannels > 0 ) 14 { 15 16 17 //try to open any Channel 18 for(int i =0 ; i < GetTotalChannels() ; i++) 19 { 20 channelHandle = ChannelOpen( i ); 21 if( (unsigned int)channelHandle != 0xFFFFFFFF ) 22 { 23 //此處有疑問,nport 不知道是什麼 24 nport = i ; 25 break; 26 } 27 } 28 29 //system("pause"); 30 31 // 若是 open channel 成功 32 if( (unsigned int)channelHandle != 0xFFFFFFFF ) 33 { 34 //註冊畫圖回調函數 35 //RegisterDrawFun(); 36 37 SetOverlayColorKey( RGB(10,10,10) ); 38 39 40 //設置視頻預覽模式: overlay 41 int supportOverlayFlag = SetPreviewOverlayMode( true ); 42 43 if( supportOverlayFlag != 0 ) 44 { 45 //不支持 overlay, 就報錯 46 } 47 48 //CWnd wnd; 49 //wnd.m_hwnd; 50 51 // StartVideoPreview( channelHandle, wnd.GetSafeHwnd() , 52 UCHAR imageBuf[704 * 576 * 2]; 53 DWORD Size = 704 * 576* 2; 54 DWORD hSize=704 * 576* 2; 55 UCHAR *imageBuffer=new UCHAR[hSize]; 56 cvNamedWindow("image",0); 57 while(1) 58 { 59 GetJpegImage(channelHandle, imageBuf, &Size, 50); 60 61 CvMat mat = cvMat(704,576,CV_8UC1, imageBuf); 62 63 IplImage *pIplImage = cvDecodeImage( &mat, 1 ); 64 65 //memcpy(imageBuffer,imageBuf,Size); 66 //IplImage *pIplImage=cvCreateImage(cvSize(704,576),8,1); 67 if(pIplImage) 68 { 69 //memcpy(pIplImage->imageData,imageBuf,Size); 70 cvShowImage("image",pIplImage); 71 cvReleaseImage(&pIplImage); 72 } 73 if(cvWaitKey(100)==27) 74 break; 75 } 76 77 78 } 79 } 80 }
第一種方法運行起來有點慢,多是解壓圖片數據要耗時間罷。對象
第二種方法:從yuv422獲得灰度圖像,而後生成IplImage對象。blog
採集卡輸出的是 原始yuv422格式圖像圖片
如下程序僅能夠 實現 灰度圖像(只提取了Y份量)的輸出。
若是想獲得彩色圖像,還須要把 yuv422格式圖像 轉成 RGB格式的
如下是一段 簡單的 視頻卡驅動 和 用openCV顯示圖像的代碼
1 // TestSDK.cpp : 定義控制檯應用程序的入口點。 2 // 3 4 #include "stdafx.h" 5 6 #define _AFXDLL 7 #include <afxwin.h> 8 9 #include "cv.h" 10 #include "highgui.h" 11 12 13 #pragma comment (lib, "DS40xxSDK.lib") 14 15 16 #include "DataType.h" 17 #include "HikVisionSdk.h" 18 19 20 21 void testCardAPI(); 22 23 int _tmain(int argc, _TCHAR* argv[]) 24 { 25 testCardAPI(); 26 return 0; 27 } 28 29 void testCardAPI() 30 { 31 HANDLE channelHandle ; 32 DWORD nport; 33 34 //initialize the card 35 36 SetDefaultVideoStandard(StandardPAL); //returns 0 if error 37 38 //返回通道個數 39 int nChannels = InitDSPs(); 40 41 if( nChannels > 0 ) 42 { 43 44 45 //try to open any Channel 46 for(int i =0 ; i < GetTotalChannels() ; i++) 47 { 48 channelHandle = ChannelOpen( i ); 49 if( (unsigned int)channelHandle != 0xFFFFFFFF ) 50 { 51 //此處有疑問,nport 不知道是什麼 52 nport = i ; 53 break; 54 } 55 } 56 57 //system("pause"); 58 59 // 若是 open channel 成功 60 if( (unsigned int)channelHandle != 0xFFFFFFFF ) 61 { 62 //註冊畫圖回調函數 63 //RegisterDrawFun(); 64 65 SetOverlayColorKey( RGB(10,10,10) ); 66 67 68 //設置視頻預覽模式: overlay 69 int supportOverlayFlag = SetPreviewOverlayMode( true ); 70 71 if( supportOverlayFlag != 0 ) 72 { 73 //不支持 overlay, 就報錯 74 } 75 76 //CWnd wnd; 77 //wnd.m_hwnd; 78 79 // StartVideoPreview( channelHandle, wnd.GetSafeHwnd() , 80 UCHAR imageBuf[704 * 576*2]; 81 DWORD Size = 704 * 576*2; 82 DWORD hSize=704 * 576; 83 UCHAR *imageBuffer=new UCHAR[hSize]; 84 cvNamedWindow("image",0); 85 while(1) 86 { 87 GetOriginalImage(channelHandle, imageBuf, &Size); 88 memcpy(imageBuffer,imageBuf,hSize); 89 IplImage *pIplImage=cvCreateImage(cvSize(704,576),IPL_DEPTH_8U,1); 90 if(pIplImage) 91 { 92 memcpy(pIplImage->imageData,imageBuffer,hSize); 93 cvShowImage("image",pIplImage); 94 cvReleaseImage(&pIplImage); 95 } 96 if(cvWaitKey(100)==27) 97 break; 98 } 99 100 101 } 102 } 103 }
關鍵之處在
1 UCHAR imageBuf[704 * 576*2]; 2 DWORD Size = 704 * 576*2; 3 DWORD hSize=704 * 576; 4 UCHAR *imageBuffer=new UCHAR[hSize]; 5 cvNamedWindow("image",0); 6 while(1) 7 { 8 GetOriginalImage(channelHandle, imageBuf, &Size); 9 memcpy(imageBuffer,imageBuf,hSize); 10 IplImage *pIplImage=cvCreateImage(cvSize(704,576),IPL_DEPTH_8U,1); 11 if(pIplImage) 12 { 13 memcpy(pIplImage->imageData,imageBuffer,hSize); 14 cvShowImage("image",pIplImage); 15 cvReleaseImage(&pIplImage); 16 } 17 if(cvWaitKey(100)==27) 18 break; 19 }