记住新建项目后,要配置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换成你自己命名的项目名)

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

 

【OpenCV】【MFC】图片、视频、摄像头输入响应【详细图解】的更多相关文章

  1. opencv4-highgui之视频的输入和输出以及滚动条

    这是<opencv2.4.9tutorial.pdf>的highgui的三个例子.通过简短的介绍来实现不同函数的理解,省去一些不需要说的东西. 一.增加滑动条 这是opencv中为数不多的 ...

  2. 摄像头脸部识别 (1)opencv 抓取视频数据并保存

    摄像头脸部识别 (1)opencv 抓取视频数据并保存 基于python 和 opencv 3.4.0 (兼容 opencv 2.X 参考注释),详细如代码 import numpy as np im ...

  3. MFC上显示摄像头JPEG图片数据的两种方法

    其一是借助opencv,其二是利用流对象. 方法一: CvMat *mat; ,,CV_8UC1); ,,CV_8UC1,JPEGBuf); /*初始化矩阵信息头,这里的JPEGBuf就是JPEG图像 ...

  4. 基于OpenCv和swing的图片/视频展示Java实现

    基于OpenCv和swing实现图片/视频的展示 图片的展示 swing展示图片,多为操作BufferedImage,这里要关注的核心是将Mat转为BufferedImage. 代码如下: publi ...

  5. 【转】MFC 自定义edit 限制输入十六进制内容 响应复制粘贴全选剪切的功能

    参考地址:MFC 自定义edit 限制输入内容 响应复制粘贴全选剪切的功能   Ctrl组合键ASCII码 ^Z代表Ctrl+z                     ASCII值 控制字符  AS ...

  6. javacpp-opencv图像处理3:使用opencv原生方法遍历摄像头设备及调用(增加实时帧率计算方法)

    javaCV图像处理系列: javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置.大小.粗度.翻转.平滑等操作 javaCV图像处理之2:实时视频添加图片水 ...

  7. OpenCV Python 录制视频

    调用摄像头 引入库支持 初始化 调整界面大小 实时显示 录制视频并保存 fourcc问题解决 代码实现 效果展示 总结 学到实用OpenCV调用笔记本电脑的摄像头,并录制视频保存到本地硬盘的时候,出现 ...

  8. 【计算机视觉】opencv读取多个摄像头

    [计算机视觉]opencv读取多个摄像头 标签(空格分隔): [图像处理] 说明:今天蹭了机器视觉课程,讲到了stereopsis,立体视觉,讲到了关于通过多个摄像头获取object的depth信息的 ...

  9. 使用图片视频展示插件blueimp Gallery改造网站的视频图片展示

    在很多情况下,我们网站可能会展示我们的产品图片.以及教程视频等内容,结合一个比较好的图片.视频展示插件,能够使得我们的站点更加方便使用,也更加酷炫,在Github上有很多相关的处理插件可以找来使用,有 ...

随机推荐

  1. Cookie,Sesstion,Application 缓存。

    Cookie客户端缓存. 1.引言 随着浏览器的处理能力不断增强,越来越多的网站开始考虑将数据存储在「客户端」,那么久不得不谈本地存储了. 本地存储的好处: 一是避免取回数据前页面一片空白,如果不需要 ...

  2. IO流的复习笔记

    IO字节流和缓冲流 IO字节流的读取和写入 读取 import java.io.FileInputStream; import java.io.FileNotFoundException; impor ...

  3. JAVA基础之——JDK分析io、nio

    在哪儿:jdk\jre\lib\rt.jar package java.io;   package java.nio; 1 分类 1.1 IO 持久化序列化对象并压缩步骤 new FileOutput ...

  4. 个人所得税计算java版

    年关将至,该到了发年终奖的时候了.所以就到网上去找下,个税计算器,但是发现做的有点像病毒网站似的.所以计算结果也不太敢信,于是琢磨着,要不自己动手写一个个税计算器吧. 说干就干,先上国家税务局了解了下 ...

  5. java EE 新手入门了解

    郑重申明:本文转载至https://blog.csdn.net/Neuf_Soleil/article/details/80962686,在此深表感谢! 为什么选择java? 想必有很多初学者会像我一 ...

  6. 使用 NamedScope 扩展 Ninject 的 InRequestScope

    背景 C#,Ninject,定期执行某计划任务.首先想到的是使用 Quartz 来安排计划任务,于是看是否有相应的集成.果然有:https://github.com/dtinteractive/Nin ...

  7. MySQL并发控制

    并发即指在同一时刻,多个操作并行执行.MySQL对并发的处理主要应用了两种机制——是“锁”和“多版本控制”. 锁 锁分为读锁和写锁两种,也称作共享锁和排他锁.因为多个读操作同时进行是不会破坏数据的,所 ...

  8. 理解域名插槽:slot-scope

    作用域插槽 | 带数据的插槽 最后,就是我们的作用域插槽.这个稍微难理解一点.官方叫它作用域插槽,实际上,对比前面两种插槽,我们可以叫它带数据的插槽.什么意思呢,就是前面两种,都是在组件的templa ...

  9. 测试canvas绘制旋转文字的性能

    canvas 绘制各种动画效果时,我们经常会使用画布旋转,使绘制上去的元素有旋转的效果. 最近在项目中碰到了很严重的性能问题,经常排查发现是因为绘制批量文字时使用了画布旋转,且每行文字的旋转角度是不一 ...

  10. drupal的权限设置

    通过hook_menu()设置url的权限,有两种方式: 方式一:定义函数,通过 access callback 'access callback' => 'fun()', function f ...