OpenCV244+VS2010下编制的摄像头摄像程序
学习OpenCV244编制的摄像程序.。
一、主要功能:
1. 开始摄像;
2. 暂停摄像并对对取景框图像存盘;
3. 继续摄像;
4. 停止摄像;
5. 打开图像文件;
6. 另存图像文件;
7. 简单图像处理。
二、实现技术:
1、安装配置。
2、程序界面的最大化。
3、二个工具条在应用程序启动时在主菜单的下面排成一行。
4、namedWindow 建立的窗口置顶方法。
5、取景框的设计。
6、OpenCV下MAT格式图像文件的存盘。
三、技术说明
1、安装配置。
到OpenCV中文网站http://www.opencv.org.cn 下载244版本,安装运行OpenCV-2.4.4.exe到G:\tdown\opencv目录下。
在VS2010 C++下建立一个解决方案CamImage,
1) 添加包含目录:
项目——属性——VC++目录——包含目录
$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include;G:\tdown\opencv\build\include;G:\tdown\opencv\build\include\opencv;G:\tdown\opencv\build\include\opencv2;
2) 添加库目录:
项目——属性——VC++目录——库目录
$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib;G:\tdown\opencv\build\x86\vc10\lib
3) 添加附加依赖项:
项目——属性——链接器——输入——附加依赖项
kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opencv_features2d244d.lib;opencv_highgui244d.lib;opencv_core244d.lib;opencv_imgproc244d.lib;opencv_ml244d.lib;opencv_objdetect244d.lib;opencv_video244d.lib;opencv_contrib244d.lib;opencv_calib3d244d.lib;%(AdditionalDependencies)
安装配置完毕。
2、程序界面的最大化。
在程序主窗体程序MainFrm.cpp创建函数 CMainFrame::OnCreate的末尾加入代码:
ShowWindow(SW_SHOWMAXIMIZED);
3、二个工具条在应用程序启动时在主菜单的下面排成一行。
在程序主窗体程序MainFrm.cpp追加函数:
void CMainFrame::DockControlBarLeftOf(CToolBar*Bar,CToolBar* LeftOf)
{
CRect rect;
DWORD dw;
UINT n; // get MFC to adjust the dimensions of alldocked ToolBars
//so that GetWindowRect will be accurate
RecalcLayout();
LeftOf->GetWindowRect(&rect);
rect.OffsetRect(1,0);
dw=LeftOf->GetBarStyle();
n = 0;
n = (dw& CBRS_ALIGN_TOP)?AFX_IDW_DOCKBAR_TOP :n;
n = (dw& CBRS_ALIGN_BOTTOM &&n==0) ?AFX_IDW_DOCKBAR_BOTTOM :n;
n = (dw& CBRS_ALIGN_LEFT && n==0)?AFX_IDW_DOCKBAR_LEFT :n;
n = (dw& CBRS_ALIGN_RIGHT &&n==0) ?AFX_IDW_DOCKBAR_RIGHT :n;
DockControlBar(Bar,n,&rect);
}
在程序主窗体程序MainFrm.cpp创建函数 CMainFrame::OnCreate的加入代码:
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); //可停靠任意位置
m_wndSizeToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar,AFX_IDW_DOCKBAR_TOP);
DockControlBarLeftOf(&m_wndSizeToolBar,&m_wndToolBar);//紧接着前一个停靠
4、namedWindow 建立的窗口置顶方法。
引自sing_sing博客 http://blog.csdn.net/sing_sing/article/details/6126466
opencv中通过cvGetWindowHandle可以获取窗口句柄。
但cvNameWindow创建窗口的时候会创建两个窗口,一个主窗口,一个子窗口。
源代码如下:
CV_IMPL intcvNamedWindow( const char* name, int flags )
{
...... ......
HWND hWnd, mainhWnd;
CvWindow* window;
DWORD defStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
...... ......
mainhWnd =CreateWindow( "Main HighGUI class", name, defStyle | WS_OVERLAPPED,
rect.x, rect.y, rect.width, rect.height, 0, 0, hg_hinstance, 0 );
if( !mainhWnd )
CV_ERROR( CV_StsError, "Frame window can not be created" );
ShowWindow(mainhWnd,SW_SHOW);
//YV- removeone border by changing the style
hWnd = CreateWindow("HighGUI class", "", (defStyle &~WS_SIZEBOX) | WS_CHILD, CW_USEDEFAULT, 0, rect.width, rect.height, mainhWnd,0, hg_hinstance, 0);
if( !hWnd )
CV_ERROR( CV_StsError, "Frame window can not be created" );
ShowWindow(hWnd,SW_SHOW);
...... ......
}
所以调用窗口句柄时需调用两次。具体实现
namedWindow( "拍照", 0 );
//--------------置顶--------------
HWND hWnd =(HWND)cvGetWindowHandle("拍照");
HWND hRawWnd = ::GetParent(hWnd);
if (hRawWnd != NULL) {
BOOL bRet = ::SetWindowPos(hRawWnd, HWND_TOPMOST,200, 100, 700, 500, SWP_NOSIZE |SWP_NOMOVE);
assert(bRet);
}
5、取景框的设计。
1)拍照时画取景框
m_Video >> frame;
frame.copyTo(imageCam);
//-------------------
Size imggeCameSize=imageCam.size();
// 画-一个绿色的取景框
line(imageCam,Point(nCamX1-1,nCamY1-1), Point(nCamX1-1,nCamY2), Scalar(0,255,0), 1, CV_AA);
line(imageCam,Point(nCamX1-1,nCamY1-1), Point(nCamX2,nCamY1-1), Scalar(0,255,0), 1, CV_AA);
line(imageCam,Point(nCamX1-1,nCamY2), Point(nCamX2,nCamY2), Scalar(0,255,0), 1, CV_AA);
line(imageCam,Point(nCamX2,nCamY1-1), Point(nCamX2,nCamY2), Scalar(0,255,0), 1, CV_AA);
//-------------------
imshow( "拍照?", imageCam );
2)存盘时截取取景框
cv::Mat roi(imageCam,Rect(nCamX1,nCamY1,nCamX2-nCamX1,nCamY2-nCamY1));
注意,Rect 后2个参数是宽和高
6、OpenCV下MAT格式图像文件的存盘。
Mat类型较CvMat和IplImage有更强的矩阵运算能力,支持常见的矩阵运算(参照Matlab中的各种矩阵运算),所以将IplImage类型和CvMat类型转换为Mat类型更易于数据处理。
Mat类型可用于直接存储图像信息,通过函数imread、imwrite、imshow等实现(与Matlab中的函数相似),似乎在新版本中开始取代IplImage类型。而之前很多存盘例子以IplImage类型存盘为主。
MAT 格式图像文件的存盘如下:
int n0=1;
// Mat roi 为从摄像头中取得的图像信息;
cv::Mat gray;
cv::cvtColor(roi,gray,CV_RGB2GRAY);
vector<string> codes;
Mat corners;
findDataMatrix(gray, codes,corners);
drawDataMatrixCodes(roi, codes,corners);
sprintf_s(filename,"Pic%.4d.jpg", n0);
imwrite(filename, roi);