记住新建项目后,要配置OpenCV环境!参考链接http://blog.csdn.net/zy122121cs/article/details/49180541

做工程搭建框架什么的,基本的要熟练啊。

 

 其中借鉴了ww老师的代码~

新建项目,命名:

点确定,然后,我习惯用基于对话框的:然后点击完成。

从工具箱拖几个控件出来:    Combo Box组合框属性设置:

给图片随便命名个ID,再选择类型Frame:

如右图所示,框架就搭好了:

 

在Test01Dlg.h头文件中添加如下:

//包含Opencv库函数
#include <iostream>
#include <vector>
#include <io.h>
#include <direct.h>
#include <stdio.h>
#include <afxwin.h> #include "opencv2/imgproc/imgproc.hpp"//图像处理函数基本模块,包括图像滤波、图像几何变换、色彩空间转换等
#include "opencv2/highgui/highgui.hpp"//视频捕捉,图像视频读取解码,图形交互
#include "afxwin.h" using namespace std;
using namespace cv;

继续在这里加以下代码,定义枚举类型和私有变量:

private:
//定义枚举类型
typedef enum {ememVIDEO_IN, emPICTURES_IN,emCAMERA_IN } READ_METHOD;//读入方式,图像0,分为相机1,视频2读入
typedef enum {emVIEWBEF, emVIEWAFT } SHOW_WINDOW;//读入窗口,0为第一个窗口,2为第二个窗口 //全局私有变量
VideoCapture cap_VidCam;//获取相机输入或者本地视频
cv::Mat m_frmBef;//原图像
int inputType;//选择的数据输入方式
int nImageWidth;//记录或设置的图像宽度
int nImageHeight;//记录或设置的图像高度
CString workDir;//图像初始默认文件夹

初始化部分BOOL CTest01Dlg::OnInitDialog():

 BOOL CTest01Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 //初始化视频数据读入方法
com_InputStyle.SetCurSel();
inputType=emPICTURES_IN; //将OpenCV中的窗口显示在MFC中
namedWindow("emVIEWBEF", WINDOW_AUTOSIZE);
HWND hWnd = (HWND) cvGetWindowHandle("emVIEWBEF");
HWND hParent = ::GetParent(hWnd);
::SetParent(hWnd, GetDlgItem(IDC_FRMBEF)->m_hWnd);
::ShowWindow(hParent, SW_HIDE); UpdateData( FALSE );//更新界面控件 //将OpenCV中的窗口显示在MFC中
workDir = F_InitWorkDir();//判断Imgs及SaveFrame文件夹是否存在,不存在创建(ww) //初始化图像显示控件的图像
CRect rect;
GetDlgItem(IDC_FRMBEF) ->GetClientRect( &rect );
m_frmBef = Mat::zeros(rect.Height(), rect.Width(), CV_8UC3); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}

void CTest01Dlg::OnPaint()部分:

 void CTest01Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), ); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + ) / ;
int y = (rect.Height() - cyIcon + ) / ; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint(); CDialog::UpdateWindow(); // 更新windows窗口,如果无这步调用,图片显示还会出现问题
if (!m_frmBef.empty())
{
F_ShowImage(emVIEWBEF,m_frmBef); // 重绘图片函数
}
}
}

单击combo box组合框右键,给图像输入方式下拉框关联变量:

然后,给变量命个名:

单击组合框右键,选择“添加事件处理程序”

给函数命名:

然后编辑该函数,加一行代码:

类似的给“选择”按钮添加函数,代码如下:

 // 根据选择不同,分别做摄像头输入,视频输入,本地图像组输入背景建模处理
void CTest01Dlg::OnBnChoosePicture()
{
// TODO: 在此添加控件通知处理程序代码
if (inputType==emPICTURES_IN)//(1)如选择图像输入
{
StopCam();//停止相机工作
string frmPath;
frmPath = DoSelectFiles(
_T("*.bmp"),
OFN_ENABLESIZING |OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY,
_T("image files (*.bmp; *.png; *.jpg) |*.bmp; *.png; *.jpg; *.jpeg| All Files (*.*) |*.*||"),
_T("选择图像序列"),
workDir+"\Imgs");
m_frmBef=cv::imread(frmPath);//读取图像
F_ShowImage(emVIEWBEF,m_frmBef);
}
else if(inputType==emCAMERA_IN)//(2)如选择视频输入
{
//摄像头输入,设置摄像头显示分辨率
nImageWidth = ;
nImageHeight = ;
//打开第一个摄像头
if ( !cap_VidCam.open() )
{
AfxMessageBox(_T("打开摄像头失败!"));
return;
}
cap_VidCam.set(CV_CAP_PROP_FRAME_WIDTH, nImageWidth); //cv设置视频流的帧宽度(只对摄像头有效)
cap_VidCam.set(CV_CAP_PROP_FRAME_HEIGHT, nImageHeight);//cv设置视频流的帧高度(只对摄像头有效)
// 启动摄像头后显示实时画面
SetTimer(, , NULL); // 10ms 定时显示
while() {
cap_VidCam >> m_frmBef;
if(m_frmBef.empty()) break;
F_ShowImage(emVIEWBEF,m_frmBef);
if(waitKey()>)break;
}
cap_VidCam.release();
}
else//(3)如选择视频输入
{
CStringA videoFiles;//存储文件的名字
StopCam();//停止相机工作
videoFiles = DoSelectFiles(
_T("*.avi"),
OFN_ENABLESIZING |OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY,
_T("video files (*.avi) |*.avi| All Files (*.*) |*.*||"),
_T("选择视频文件"),
workDir+"\Videos");
cap_VidCam.open(LPCSTR(videoFiles));//打开文件
SetTimer(, , NULL); // 10ms 定时显示
while() {
cap_VidCam >> m_frmBef;
if(m_frmBef.empty()) break;
F_ShowImage(emVIEWBEF,m_frmBef);
if(waitKey()>)break;
}
cap_VidCam.release();
}
}

继续在下面添加 关闭摄像头部分 代码:

 //关闭摄像头
void CTest01Dlg::StopCam()
{
if (cap_VidCam.isOpened())
{
KillTimer();//该函数移除先前用SetTimer设置的定时器,在定时器使用完毕后移除定时器时使用
// 对图像数据清零
m_frmBef = Scalar();
cap_VidCam.release();//释放VideoCapture对象
}
}

打开文件对话框相关代码:

 //弹出打开文件对话框,选择单个文件,并可以限制文件类型
CStringA CTest01Dlg::DoSelectFiles(
LPCTSTR lpszDefExt,
DWORD dwFlags,
LPCTSTR lpszFilter,
LPCSTR lpstrTitle,
LPCSTR lpstrInitialDir )
{
CStringA selectedFile;
POSITION filePosition; CFileDialog dlg( TRUE, lpszDefExt, NULL, dwFlags, lpszFilter, NULL );
dlg.m_ofn.lpstrFile[] = NULL;
dlg.m_ofn.lpstrTitle = lpstrTitle;
dlg.m_ofn.lpstrInitialDir = lpstrInitialDir; if( dlg.DoModal() == IDOK )
{
selectedFile = dlg.GetPathName();
}
return selectedFile;
}
//初始化(创建)程序运行所需的文件夹
CString CTest01Dlg::F_InitWorkDir()
{
CStringA strPath;
TCHAR path[_MAX_PATH];
TCHAR drive[_MAX_DRIVE];
TCHAR dir[_MAX_DIR];
TCHAR fname[_MAX_FNAME];
TCHAR ext[_MAX_EXT];
::GetModuleFileName(AfxGetApp()->m_hInstance, path, _MAX_PATH);
_tsplitpath(path, drive, dir, fname, ext); strPath.Empty();
strPath += CString(drive);
strPath += CString(dir); string saveDir = strPath;
saveDir += "/Imgs";
F_CheckDir(saveDir, true);
saveDir = strPath;
saveDir += "/Videos";
F_CheckDir(saveDir, true);
saveDir = strPath;
saveDir += "/SaveFrame";
F_CheckDir(saveDir, true); return CString(strPath);
}
//检查文件夹是否存在
bool CTest01Dlg::F_CheckDir(const string dir, bool creatDir /* = false */)
{
bool RetVal = false; string fileName = dir;
fileName += "\\*"; _finddata_t FileInfo;
long Handle = _findfirst(fileName.c_str(), &FileInfo); if (Handle == -1L)
{
if (creatDir)
{
if(_mkdir(dir.c_str())==)
{
RetVal = true;
}
}
}
else
{
RetVal = true;
_findclose(Handle);
}
return RetVal;
}

显示图像部分 代码:

 //显示图像,将要绘制的图像 src 复制到 des,然后绘制到控件号为 ID 的 Picture 控件
void CTest01Dlg::F_ShowImage(int type,Mat& src)
{
cv::Mat m_dst;
CRect rect;
GetDlgItem(IDC_FRMBEF)->GetClientRect(&rect);
cv::Rect dst(rect.left,rect.top,rect.right,rect.bottom);
cv::resize(src,m_dst,cv::Size(rect.Width(),rect.Height()));
if (type==emVIEWBEF)
{
imshow("emVIEWBEF", m_dst);
}
}

然后别忘了给“保存图片”按钮 添加响应函数:

 void CTest01Dlg::OnBnClickedSaveImage()
{
//定义可以保存的图像类型后缀名
CString csBMP="BMP Files(*.BMP)|*.BMP|";
CString csJPG="JPG Files(*.JPG)|*.JPG|";
CString csTIF="TIF Files(*.TIF)|*.TIF|";
CString csPNG="PNG Files(*.PNG)|*.PNG|";
CString csDIB="DIB Files(*.DIB)|*.DIB|";
CString csPBM="PBM Files(*.PBM)|*.PBM|";
CString csPGM="PGM Files(*.PGM)|*.PGM|";
CString csPPM="PPM Files(*.PPM)|*.PPM|";
CString csSR ="SR Files(*.SR) |*.SR|";
CString csRAS="RAS Files(*.RAS)|*.RAS||"; CString csFilter=csBMP+csJPG+csTIF+csPNG+csDIB
+csPBM+csPGM+csPPM+csSR+csRAS; CString name[]={"","bmp","jpg","tif","png","dib",
"pbm","pgm","ppm","sr", "ras",""}; CString strFileName;
CString strExtension; CString defaultDir = workDir+"\SaveFrame"; //默认打开的文件路径
CString fileName = "new.bmp"; //默认保存的文件名 CFileDialog openFileDlg(false,".bmp", fileName, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, csFilter, NULL);
openFileDlg.m_ofn.lpstrInitialDir=defaultDir;//初始化路径
// 文件存盘对话框
if (openFileDlg.DoModal()==IDOK ) // 输入了文件名
{
strFileName = openFileDlg.m_ofn.lpstrFile;
if (openFileDlg.m_ofn.nFileExtension == ) // 无文件后缀
{
strExtension = name[openFileDlg.m_ofn.nFilterIndex];
strFileName = strFileName + '.' + strExtension;
// 加文件后缀
} string s(strFileName.GetBuffer());
imwrite(s,m_frmBef); // 当前画面存盘
}
}

给“关闭”按钮添加响应函数:

 void CTest01Dlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
StopCam();//停止相机工作
CDialogEx::OnOK();
}

注:以上代码均加在Test01Dlg.cpp中(Test01换成你自己命名的项目名)

然后这个简单的框架就搭好啦!    ^-^

 

最新文章

  1. Windows Server 2008 双网卡同时上内外网 不能正常使用
  2. 【转载】Shell判断字符串包含关系的几种方法
  3. HTML5 Canvas眨眼睛动画
  4. Wireshark查看https的通讯
  5. XE7 &amp; IOS开发之开发账号(2):发布证书、发布授权profile的申请使用,附Ad hoc真机调试、生成ipa文件演示(XCode所有版本通用,有图有真相)
  6. 素数筛 uva 543
  7. IP分片浅析
  8. windows路由命令route
  9. QTableView的表格项中加入图标的方法(重载View::mouseMoveEvent,并使用View::setIconSize函数设置图标的大小)
  10. .NET自带IOC
  11. 201521123036 《Java程序设计》第3周学习总结
  12. c专家编程摘录
  13. EventBus 线程切换原理
  14. Eclipse4.8.0的svn插件离线安装说明
  15. prepareRefresh()方法源码探究
  16. Oracle 11g rac 添加新节点测试
  17. PAT 1022 D进制的A+B (20)(20 分)
  18. vue仿微信网页版|vue+web端聊天室|仿微信客户端vue版
  19. MySQL数据库之视图
  20. Linux系统——MySQL基础(二)

热门文章

  1. vue-pdf的3.3.1版本build后多生成168个js文件
  2. c# 中 event 和 delegate 的区别
  3. dapper 多对多查询对象和对象列表
  4. Java - 谨慎实现Comparable接口
  5. hdu 1159(DP+字符串最长公共序列)
  6. js类的笔记
  7. 有关动态规划(主要是数位DP)的一点讨论
  8. javascript 获取服务时间
  9. AngularJS 最常用指令的功能
  10. 然之协同系统6.4.1 SQL注入导致getshell