主要流程是:封装一个ocx控件,其中包含了opencv打开摄像头的函数,接着在windows下注册ocx,并用html的Object标签加载ActiveX控件
具体步骤:
一、测试摄像头调用函数
1、新建MFC ActiveX控件
2、在ctrl头文件中定义openCamera函数
3、ctrl.cpp文件中进行调度映射,使用DISP_FUNCTION函数,加载openCamera函数
4、ctrl.cpp文件中使用Cctrl::openCamera()来编写实现函数,用到VedioCapture类、Mat图像矩阵类,imshow调用默认对话框显示摄像头图像,while(1){waitKey(30)};反复执行
5、Mat转换为CImage
(1)对一些异常情况的处理:矩阵元素总个数mat.total为0,通道数不等于1或者3,这两种情况返回错误值,提示无法转换
(2)获取图像宽高,width=mat.cols height=mat.rows
(3)重建cImage,调用destroy方法和create方法,创建RGB模式图像,3通道各8位深度,一共24位(3*channels)
(4)拷贝数据,如果是单通道,创建灰度模式图像,初始化调色板,设置8位深度(256),并设置调色板数组的每个元素的RGB默认值,为cImage设置新的调色板,删除调色板临时数组
(5)设置mat行指针、cImage位的指针和cImage每行的字节数,拷贝数据,通过两个for循环,将cImage指针指向对应的mat数组元素
代码引用:https://blog.csdn.net/liangjialang/article/details/33320093
void MatToCImage(Mat& mat, CImage& cimage)
{
if (0 == mat.total())
{
return;
}
int nChannels = mat.channels();
if ((1 != nChannels) && (3 != nChannels))
{
return;
}
int nWidth = mat.cols;
int nHeight = mat.rows;
//重建cimage
cimage.Destroy();
cimage.Create(nWidth, nHeight, 8 * nChannels);
//拷贝数据
uchar* pucRow; //指向数据区的行指针
uchar* pucImage = (uchar*)cimage.GetBits(); //指向数据区的指针
int nStep = cimage.GetPitch(); //每行的字节数,返回值有正有负
if (1 == nChannels) //对于单通道的图像需要初始化调色板
{
RGBQUAD* rgbquadColorTable;
int nMaxColors = 256;
rgbquadColorTable = new RGBQUAD[nMaxColors];
cimage.GetColorTable(0, nMaxColors, rgbquadColorTable);
for (int nColor = 0; nColor < nMaxColors; nColor++)
{
rgbquadColorTable[nColor].rgbBlue = (uchar)nColor;
rgbquadColorTable[nColor].rgbGreen = (uchar)nColor;
rgbquadColorTable[nColor].rgbRed = (uchar)nColor;
}
cimage.SetColorTable(0, nMaxColors, rgbquadColorTable);
delete []rgbquadColorTable;
}
for (int nRow = 0; nRow < nHeight; nRow++)
{
pucRow = (mat.ptr<uchar>(nRow));
for (int nCol = 0; nCol < nWidth; nCol++)
{
if (1 == nChannels)
{
*(pucImage + nRow * nStep + nCol) = pucRow[nCol];
}
else if (3 == nChannels)
{
for (int nCha = 0 ; nCha < 3; nCha++)
{
*(pucImage + nRow * nStep + nCol * 3 + nCha) = pucRow[nCol * 3 + nCha];
}
}
}
}
}
6、F7快速生成ocx
二、使用regsvr32 …ocx命令注册ocx控件
三、html中放置按钮,并在点击事件中添加调用ocx的方法,Object中的style定义了摄像头窗口的大小,与ctrl,cpp文件中OnDraw方法相对应,Object的classid值与idl文件中ctrl的uuid相对应
四、在IE中允许ActiveX控件,并运行程序
遇到的问题:
一、引入Mat类时,要包含opencv中的higngui头文件,必须使用cv命名空间
二、引入CImage类时,必须先包含atlimage.h再包含stdafx.h
三、测试时,必须使用IE浏览器,加载ActiveX控件
扩展:CImage转换为Mat
原理同Mat转CImage
(1)初始化mat时,采用CV_8UC1和CV_8UC3两种类型
(2)不需要借助调色板,直接由图像转为矩阵