• 海康威视采集卡结合opencv使用(两种方法)-转


    (注:第一种方法是我的原创 ^_^。 第二种方法是从网上学习的。)

    第一种方法:利用 板卡的API:  GetJpegImage 得到 Jpeg 格式的图像数据,然后用opencv里的一个函数进行解码,得到IplImage对象。(我很郁闷海康威视采集卡为什么不直接提供RGB图像数据,而是提供了一个Jpeg数据给用户。)

    libjpeg库就是专门处理 jpeg 格式的图像数据的,包括解码缩jpeg 格式的图像等。

    opencv的库依赖于libjpeg库。我看了libjpeg库的源代码,然后又看了opencv 里 cvLoadImage这部分的源代码,发现opencv已经封装好了一个图像解码器: cvImageDecoder.

    而且opencv的API 还提供了一个解码 内存中的图像数据的函数:

    CVAPI(IplImage*) cvDecodeImage( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));

    先生成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对象。

    采集卡输出的是 原始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 }
  • 相关阅读:
    结构体
    指针
    数组
    银行取款机系统
    函数
    基础
    IOS系统的安装和Vi的操作模式以及简单的指令
    1203.4——循环语句 之 for
    1203.3——循环语句 之 while
    1203.2——条件语句 之 switch语句
  • 原文地址:https://www.cnblogs.com/xingrun/p/3402940.html
Copyright © 2020-2023  润新知