【OpenCV】用OpenCV进行大恒CG400CG410视频采集卡的视频读取

用OpenCV进行大恒CG400CG410视频采集卡的视频读取
 (2013-04-27 16:12:02)

分类: opencv
最近用到红外摄像头,要用到视频采集卡,采用的是大恒CG410的板子,CG410是CG400的升级版,虽然驱动不一样,SDK和适用环境是一样的。这是使用的是win7 32位系统。
大恒的SDK的事例都是都是MFC的代码,奈何我需要的是在控制台下进行摄像头的读取,并转换到OpenCV可以识别的图像数据格式IplImage或者Mat结构,这个使用的是前者。
下面是解决方法:
在项目的库中包含
CGVideo.lib 
CGVidEx.lib
头文件记得加入windows.h,因为要使用到windows句柄
代码如下:
1: #include "opencv2/core/core.hpp"
2: #include "opencv2/highgui/highgui.hpp"
3: #include "opencv2/imgproc/imgproc.hpp"
4: #include "opencv2/video/video.hpp"
5: #include <iostream>
6: #include <windows.h>
7: 
8: #include "CGVideo.h"
9: #include "CGDef.h"
10: #include "CGVidEx.h"
11: 
12: using namespace std;
13: using namespace cv;
14: 
15: int main()
16: {
17: //初始化所有成员变量,同时打开图像卡 */
18: CGSTATUS status = CG_OK;
19: HCG hcg = NULL;
20:
21: //打开图像卡 1,返回状态值
22: status = BeginCGCard(1, &hcg);
23:
24: //检验函数执行状态,如果失败,则返回错误状态消息框*/
25: CG_VERIFY(status);
26:
27: //初始化图像卡硬件状态,用户也可以在其他位置初始化图像卡,
28: //但应保证图像卡已经打开,建议用户在应用程序初始化时,同时初始化图像卡硬件。
29: // 设置视频制式(PAL / NTSC),由当前视频源制式决定
30: CGSetVideoStandard(hcg, PAL);
31: 
32: // 扫描模式,包括 FRAME、FIELD
33: CGSetScanMode(hcg, FRAME);
34:
35: //晶振,包括CRY_OSC_35M、CRY_OSC_28M
36: //对于DH-CG300图像卡,一般为CRY_OSC_35M,
37: //对于DH-QP300图像卡,一般为CRY_OSC_28M,
38: //其他类型图像卡没有此硬件设置,但可以调用此接口,并返回CG_NOT_SUPPORT_INTERFACE信息
39:
40: CGSelectCryOSC(hcg, CRY_OSC_35M);
41:
42: //视频格式,即采集图像数据描述方式,包括YUV422、RGB888、RGB565、RGB555、RGB8888、ALL8BIT、LIMITED8BIT,
43: //在采集图像到屏幕时,需要保证视频格式和当前系统屏幕位深度一致,而采集到 内存没有此限制。
44: CGSetVideoFormat(hcg, RGB888);
45:
46:
47: //视频源路VIDEO_SOURCE包括视频类型和序号,
48: //各种图像卡支持的视频源路不尽相同,请参看相应硬件说明
49: VIDEO_SOURCE source;
50: source.type = COMPOSITE_VIDEO; //视频类型为复合视频
51: source.nIndex = 0; //序号为0
52: CGSetVideoSource(hcg, source);
53:
54: //视频输入窗口,即视频输入范围,输入窗口取值范围:
55: //对于视频制式为PAL制,水平方向为0-768,垂直方向为0-576
56: //对于视频制式为NTSC制,水平方向为0-768,垂直方向为0-576
57: //视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
58: CGSetInputWindow(hcg, 0, 0, 768, 576); //视频输入窗口取最大
59: 
60:
61: //视频输出窗口,即视频输出范围,输出窗口取值范围必须在输入窗口范围以内,
62: //视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
63: //在采集到屏幕时,输出窗口的起始位置为图像屏幕输出位置的屏幕坐标,
64: //在采集到内存时,输出窗口的起始位置设置为(0, 0)即可。
65:
66: CGSetOutputWindow(hcg, 0, 0, 768, 576);
67: 
68: //初始化BITMAPINFO 结构指针
69: BITMAPINFO *pBmpInfo = NULL;
70: BYTE *pInfoBuffer = NULL;
71: BYTE *pImageBuffer = NULL; //BIMTAPINFO 存储缓冲区,m_pBmpInfo即指向此缓冲区
72: 
73: BYTE *pStaticBuffer = NULL; //静态内存地址指针
74: HANDLE handle = NULL; //静态内存描述句柄
75:
76: //采集1帧图像到内存,采集完成后停止
77: while (TRUE)
78: {
79: status = CGSnapShot(hcg, 0, 0, TRUE, 1);
80: CG_VERIFY(status);
81: 
82: if (CG_SUCCESS(status))
83: {
84: pInfoBuffer = new BYTE[sizeof(BITMAPINFO)];
85: if (pInfoBuffer)
86: {
87: //m_pBmpInfo即指向m_chBmpBuf缓冲区,用户可以自己分配BTIMAPINFO缓冲区
88:
89: pBmpInfo = (BITMAPINFO *)pInfoBuffer;
90:
91:
92: //初始化BITMAPINFO 结构,此结构在保存bmp文件、显示采集图像时使用
93:
94: pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
95:
96: //图像宽度,一般为输出窗口宽度
97: pBmpInfo->bmiHeader.biWidth = 768;
98:
99: //图像高度,根据扫描模式(FRAME/FIELD)的不同
100: //FRAME制下,一般为输出窗口高度
101: //FIELD制下,一般为输出窗口高度的一半
102: pBmpInfo->bmiHeader.biHeight = 576;
103:
104: //图像位深度,由视频格式确定,
105: //采集图像视频格式有RGB565、RGB555、RGB888、ALL8BIT等,
106: //如果使用CGDateTransfrom函数,则将15,16位数据转换为24位
107: pBmpInfo->bmiHeader.biBitCount = 24;
108:
109: //以下设置一般相同,
110: //对于低于8位的位图,还应设置相应的位图调色板
111: pBmpInfo->bmiHeader.biPlanes = 1;
112: pBmpInfo->bmiHeader.biCompression = BI_RGB;
113: pBmpInfo->bmiHeader.biSizeImage = 0;
114: pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
115: pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
116: pBmpInfo->bmiHeader.biClrUsed = 0;
117: pBmpInfo->bmiHeader.biClrImportant = 0;
118: 
119: //分配图像缓冲区,一般用来存储采集图像
120: //用户可以将设备静态内存的图像数据直接通过指针或
121: //用CGDataTransfrom函数拷贝到图像缓冲区,然后做进一步的处理,
122: //一般图像缓冲区大小由输出窗口大小和视频格式确定。
123: pImageBuffer = new BYTE[768 * 576 * 3];
124: if (pImageBuffer)
125: {
126: //锁定指定位置的静态内存,
127: //偏移由图像大小和图像序号确定,锁定大小为图像大小
128: //用户可以在任何时候锁定指定位置的静态内存,然后通过pLinearAddr指针访问相应的内存。
129: status = CGStaticMemLock(0, 768 * 576 * 3, &handle, (VOID **)&pStaticBuffer);
130: if (CG_SUCCESS(status))
131: {
132:
133: //将静态内存中的图像传递到用户缓冲区,同时进行格式转换。
134: //如果静态内存中图像为15、16、32位,则转换为24位。
135: //由于图像卡采集到静态内存的图像数据是正向存放,
136: //而Windows中处理的位图数据需要倒置,因此一般还要将图像倒置。
137: CGDataTransform(pImageBuffer, //图像缓冲区
138: pStaticBuffer, //静态内存
139: 768, //图像宽度
140: 576, //图像高度
141: 24, //图像位深度
142: TRUE //是否倒置图像
143: );
144: CGStaticMemUnlock(handle); //解除静态内存锁定
145: }
146: 
147: CvSize n_size = cvSize(768,576);
148: IplImage* frame = cvCreateImageHeader( n_size, IPL_DEPTH_8U, 3 );
149: frame->imageData = (char *)pImageBuffer;
150: cvNamedWindow( "test", CV_WINDOW_AUTOSIZE );
151: cvShowImage("test",frame);
152: cvWaitKey(20);
153:
154: delete []pImageBuffer; //释放图像缓冲
155: cvReleaseImage(&frame);
156: }
157: 
158: delete []pInfoBuffer; //释放文件信息缓冲
159: }
160: }
161: 
162: }
163: // 关闭图像卡1
164: status = EndCGCard(hcg);
165: CG_VERIFY(status);
166: }
 


关于大恒图像采集卡的使用
昨天终于可以采集图像并显示了,那个高兴啊~


总结了一下使用的步骤(图像采集卡是 大恒 CG410)


使用 CGStartSnap 和 CGEndSnap 组合来控制开始和停止图像采集的步骤如下:


1、定义一个全局的设备句柄


    HCG m_hcg;


2、打开图像采集卡


    CGSTATUS status = CG_OK;
    //    打开图像卡 1
    status = BeginCGCard(1, &m_hcg);
    //    检验函数执行状态,如果失败,则返回错误状态消息框
    CG_VERIFY(status);


3、初始化图像采集卡硬件参数


    //保证图像卡已经打开
    //设置视频制式(PAL / NTSC),由当前视频源制式决定
    CGSetVideoStandard(m_hcg, PAL);        


    //视频格式,即采集图像数据描述方式,    
   //YUV422、RGB888、RGB565、RGB555、RGB8888、ALL8BIT、LIMITED8BIT,
   //采集图像到屏幕时,需要保证视频格式和当前系统屏幕位深度一致
    CGSetVideoFormat(m_hcg, RGB888);


    //扫描模式,包括 FRAME、FIELD
    CGSetScanMode(m_hcg, FRAME);


    // 设置视频源路,
    VIDEO_SOURCE source;
    source.type        = COMPOSITE_VIDEO;        //视频类型为复合视频
    source.nIndex    = 0;                    //序号为0
    CGSetVideoSource(m_hcg, source);


    //频输入窗口,即视频输入范围,输入窗口取值范围:
    //PAL (0-768,0-576 );NTSC(0-640,0-480)
    //视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
    CGSetInputWindow(m_hcg, 0, 0, 768, 576);    //视频输入窗口取最大


    //视频输出窗口,即视频输出范围,输出窗口取值范围必须在输入窗口范围以内,
    //视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
    //在采集到屏幕时,输出窗口的起始位置为图像屏幕输出位置的屏幕坐标,
    //在采集到内存时,输出窗口的起始位置设置为(0, 0)即可。
    CGSetOutputWindow(m_hcg, 0, 0, 400, 300);


4、启动采集图像到内存


    //   启动图像卡采集图像到内存
    //   指定图像卡将图像采集到静态内存偏移为0的位置,
    // 采集缓冲区大小为2幅图像大小
    status = CGStartSnap(m_hcg, 0, TRUE, 2);
    CG_VERIFY(status);    
    
    //获取当前正在采集的图像场,判定哪一帧图像已经采集完毕,可以进行处理
    status = CGGetSnappingNumber(m_hcg, &nStatus);


5、读出图像数据


    status = CGStaticMemLock(dwImageSize * nNumber, dwImageSize, &handle, (VOID **)&pStaticBuffer);
    if (CG_SUCCESS(status)) 
    {
        /*
        *    将静态内存中的图像传递到用户缓冲区,同时进行格式转换。
        *    如果静态内存中图像为15、16、32位,则转换为24位。
        *    由于图像卡采集到静态内存的图像数据是正向存放,
        *    而Windows中处理的位图数据需要倒置,因此一般还要将图像倒置。
        */
        CGDataTransform(pImageBuffer, pStaticBuffer, 400, 300, 24, TRUE);
        CGStaticMemUnlock(handle);        //解除静态内存锁定
    }


6、结束读取过程


    status = CGStopSnap(m_hcg);
    CG_VERIFY(status);


7、关闭图像采集卡


    CGSTATUS status = CG_OK;
    //    关闭图像卡,释放图像卡内部资源
    status = EndCGCard(m_hcg);
    CG_VERIFY(status);
 
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值