OpenCV与MFC实战之图像处理 样本采集小工具制作 c++MFC课程设计

时间:2022-02-05 06:34:01

原文作者:aircraft

原文链接:https://www.cnblogs.com/DOMLX/p/12111102.html

    入门不久的人可以通过opencv实战来锻炼一下学习opencv的成果,百度云链接:

链接:https://pan.baidu.com/s/1jGOD97Zx96ZDAvlkQtaPYQ
提取码:afip

运行环境VS2017,需要配置库为:opencv

题目:样本采集小工具

OpenCV与MFC实战之图像处理  样本采集小工具制作  c++MFC课程设计

需求:

用MFC和opencv完成样本采集小工具。

界面功能

1、选中原图片集的目录。

2、选择当前是正样本还是负样本?并选中其目录。

3、通过上一张下一张更换原图片集的图片显示。

鼠标点击图片显示区域功能

1、左击图片选中,以鼠标点击处为中心,宽W*高H的区域。

2、鼠标滚轮上滚扩大选中区域。

3、鼠标滚轮下滚缩小选中区域。

4、右击保存选中区域的图片在正样本或负样本的目录下,取决于当前选中正样本还是负样本。

完成界面如图:

OpenCV与MFC实战之图像处理  样本采集小工具制作  c++MFC课程设计

第一步:把MFC界面的那些控件都拖动好并且绑定好opencv图形框

在MFC的初始化函数中添加我们的绑定代码:

BOOL CpicroiDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 //InitializeSkin(("Minimized.ssk"));//初始化 // TODO: 在此添加额外的初始化代码
namedWindow("ImageShow", CV_WINDOW_KEEPRATIO); // 用OpenCV创建一个窗口
CRect cWindowRect;
m_PictureControl.GetClientRect(&cWindowRect); // 获取控件窗口大小
//int nWindowWidth = cWindowRect.Width();
//int nWindowHeight = cWindowRect.Height();
//resizeWindow("ImageShow", 200, 100);
HWND hPictureWindow = (HWND)cvGetWindowHandle("ImageShow"); // 获取OpenCV窗口的句柄
HWND hParentWindow = ::GetParent(hPictureWindow);
::SetParent(hPictureWindow, GetDlgItem(IDC_PIC)->m_hWnd); // 关联OpenCV窗口和MFC的控件窗口
::ShowWindow(hParentWindow, SW_HIDE);
GetDlgItem(IDC_PIC)->ShowWindow(); // 开始不显示图片控件 setMouseCallback("ImageShow", onMouse, ); pcom.InsertString(, "正样本");
pcom.InsertString(, "负样本");
pcom.SetCurSel(); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}

第二步:选中原图片集的目录

这样接下来操作的图片都从这个目录顺序读取,并且切换上下张

添加好对话框类之后:

双击这个控件,进入相应的编辑函数内部编写事件处理代码:

OpenCV与MFC实战之图像处理  样本采集小工具制作  c++MFC课程设计

void CpicroiDlg::OnBnClickedMainFilePath()
{
// TODO: 在此添加控件通知处理程序代 CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("image files (*.jpeg; *.jpg; *.bmp;*.png) All Files (*.*) |*.*||"));
CString m_strPath;
CString m_folderpath;
if (IDOK == dlg.DoModal()) {
m_strPath = dlg.GetPathName();
m_folderpath = dlg.GetFolderPath();
}
string strName = CT2A(m_strPath.GetString()); // CString和string之间的类型转换
string strPathNames = CT2A(m_folderpath.GetString());
sourceImage = imread(strName);
nWindowWidth = sourceImage.cols;
nWindowHeight = sourceImage.rows;
resizeWindow("ImageShow", nWindowWidth, nWindowHeight);
if (strName == "")return; tempImage = sourceImage.clone();
imshow("ImageShow", sourceImage);
GetDlgItem(IDC_PIC)->ShowWindow(); SetDlgItemText(IDC_MAIN_FILE, m_folderpath);
UpdateWindow();
getFiles1(strPathNames, files);
filesLen = files.size()-;
for (auto path : files) {
index++;
if (path == strName)break;
}
}

同样的也要选择保存的文件路径:

OpenCV与MFC实战之图像处理  样本采集小工具制作  c++MFC课程设计

void CpicroiDlg::OnBnClickedMainFilePath2()
{
// TODO: 在此添加控件通知处理程序代码
if (m_dlgMainFile.DoModal() != IDOK)
return; CString cstrFile; //文件全名
string strFile;
cstrFile = m_dlgMainFile.GetFolderPath();
strFile = CT2A(cstrFile.GetString());
SetDlgItemText(IDC_MAIN_FILE2, cstrFile);
UpdateWindow();
getFiles1(strFile, filesPath2);
picIndex = filesPath2.size();
GetDlgItem(IDC_MAIN_FILE2)->GetWindowTextA(cs_pcomValue);
s_pcomComValue = CT2A(cs_pcomValue.GetString());
}

OpenCV与MFC实战之图像处理  样本采集小工具制作  c++MFC课程设计

void CpicroiDlg::OnBnClickedMainFilePath3()
{
// TODO: 在此添加控件通知处理程序代码
if (m_dlgMainFile.DoModal() != IDOK)
return; CString strFile; //文件全名
strFile = m_dlgMainFile.GetFolderPath() + "\\";
SetDlgItemText(IDC_MAIN_FILE3, strFile);
UpdateWindow();
}

这样只要选择好了正负样本点击右键就可以自动保存到相应的选择好的目录了

第三步:鼠标控制图像的裁剪和选定

这里我们要实现的是鼠标点击出现一个矩形框,然后用鼠标的滚轮去滚动,让矩形框围绕中心点改变大小,然后点击右键则保存图形

void onMouse(int event, int x, int y, int flag, void*) {

    //CDC *pDC = GetDC();
//CString str; str.Format(TEXT("%d,%d"), x, y);
//pDC->FillSolidRect(0, 0, 100, 100, GetSysColor(COLOR_WINDOW));
//pDC->TextOut(1, 0, str);
switch (event)
{
case CV_EVENT_LBUTTONDOWN://左键按下
flag = true;
mousFlag = ;
moux = x;
mouy = y;
if ((x - width / ) < )Lu.x = ;
else Lu.x = x - width / ;
if ((y - height / ) < )Lu.y = ;
else Lu.y = y - height / ;
if ((x + width / ) > nWindowWidth - )Rd.x = nWindowWidth - ;
else Rd.x = x + width / ;
if ((y + height / ) > nWindowHeight - )Rd.y = nWindowHeight - ;
else Rd.y = y + height / ;
lastImage = tempImage.clone();
rectangle(tempImage, Lu, Rd, Scalar(, , ), , , );
imshow("ImageShow", tempImage);
break;
case CV_EVENT_RBUTTONDOWN://右键按下
{ Rect rect(Lu.x, Lu.y, Rd.x-Lu.x, Rd.y-Lu.y);
g_rect = rect;
}
if (s_pcomComValue == "")
{
MessageBox(AfxGetMainWnd()->m_hWnd, "存放目录未填写","警告", MB_OK);
break;
}
s_save = s_pcomComValue +"\\"+ to_string(picIndex) + ".jpg";
ROI = sourceImage(g_rect);
imwrite(s_save, ROI);
picIndex++;
break;
case CV_EVENT_MOUSEWHEEL:
int mousWhellFlag;
int value;
mousWhellFlag = ;
value = getMouseWheelDelta(flag);
if (value > ) {
Lu.x = Lu.x > ? Lu.x -= step : Lu.x;
Lu.y = Lu.y > ? Lu.y -= step : Lu.y; Rd.x = Rd.x < (nWindowWidth - ) ? Rd.x += step : (nWindowWidth - );
Rd.y = Rd.y < (nWindowHeight - ) ? Rd.y += step : (nWindowHeight - );
}
else {
Lu.x = Lu.x < x ? Lu.x += step : x;
Lu.y = Lu.y < y ? Lu.y += step : y; Rd.x = Rd.x > x ? Rd.x -= step : x;
Rd.y = Rd.y > y ? Rd.y -= step : y;
}
{ Rect rect(Lu.x, Lu.y, Rd.x - Lu.x, Rd.y - Lu.y); g_rect = rect; }
tempImage = lastImage.clone();
rectangle(tempImage, Lu, Rd, Scalar(, , ), , , );
imshow("ImageShow", tempImage);
break; default:
break;
} }

因为我们裁剪已经画矩形框都不能在原图上画,所以我们复制一份图像显示,所有的操作都是在复制 的临时图像上操作的,然后在根据缓冲刷新,将图像替换就行了

最后说一句,这个是直接显示原图的,如果原图过大只能看到部分,这时候在代码里面加个判断,然后用opencv的图像归一化的函数去改变一下图像大小即可。

因为不想写的很详细,(别问为什么,问就是因为最近很懒!!!),所以我给出了项目源码的百度云在文章的开头

若有兴趣交流分享技术,可关注本人公众号,里面会不定期的分享各种编程教程,和共享源码,诸如研究分享关于c/c++,python,前端,后端,opencv,halcon,opengl,机器学习深度学习之类有关于基础编程,图像处理和机器视觉开发的知识

OpenCV与MFC实战之图像处理  样本采集小工具制作  c++MFC课程设计

OpenCV与MFC实战之图像处理 样本采集小工具制作 c++MFC课程设计的更多相关文章

  1. 从C&plus;&plus;起步到MFC实战VC&plus;&plus;软件工程师高端培训 视频保存在 播音员的网盘中

    从C++起步到MFC实战VC++软件工程师高端培训(服务器端开发方向)[共332课时]视频保存在 播音员的网盘中http://www.it1352.com/VideoTutorial/Details? ...

  2. Python 图像处理 OpenCV (10):图像处理形态学之顶帽运算与黑帽运算

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  3. 《数据分析实战&colon;基于EXCEL和SPSS系列工具的实践》一1&period;4 数据分析的流程

    本节书摘来华章计算机<数据分析实战:基于EXCEL和SPSS系列工具的实践>一书中的第1章 ,第1.4节,纪贺元 著 更多章节内容可以访问云栖社区"华章计算机"公众号查 ...

  4. 如何制作带MFC界面的MFC DLL

    最近在做基于组件化MFC界面的开发,需要把界面封装到动态库中. 一:工程创建步骤 1.创建MFC DLL工程,选择 “在共享 DLL 中使用 MFC”. 2.运行时库选择:c/c++-->代码生 ...

  5. 【Opencv 小工具】鼠标选区信息获取

    有时候在目标跟踪的算法初始化工作时候,需要选区一个Rect区域,来表示要跟着的目标,所以有次小工具. 使用QT和opencv 编写 项目地址 https://github.com/wzyuliyang ...

  6. Tsar 服务器系统和应用信息的采集报告工具

    Tsar介绍 Tsar是淘宝的一个用来收集服务器系统和应用信息的采集报告工具,如收集服务器的系统信息(cpu,mem等),以及应用数据(nginx.swift等),收集到的数据存储在服务器磁盘上,可以 ...

  7. OpenCV探索之路(二十五):制作简易的图像标注小工具

    搞图像深度学习的童鞋一定碰过图像数据标注的东西,当我们训练网络时需要训练集数据,但在网上又没有找到自己想要的数据集,这时候就考虑自己制作自己的数据集了,这时就需要对图像进行标注.图像标注是件很枯燥又很 ...

  8. Python接口测试实战1(下)- 接口测试工具的使用

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  9. mfc小工具开发之定时闹钟之---多线程急线程同步

    一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...

随机推荐

  1. sqlite锁的机制

     reserved state 进入reserved state以后,sqlite可以修改数据库中的内容,不过把修改以后的内容写到pager的缓存里,大小由page cache指定. 进入这个状态以 ...

  2. Weka – 分类

    1.      weka简单介绍 1)  weka是新西兰怀卡托大学WEKA小组用JAVA开发的机器学习/数据挖掘开源软件. 2)  相关资源链接 http://sourceforge.net/pro ...

  3. BZOJ 3230&colon; 相似子串&lpar; RMQ &plus; 后缀数组 &plus; 二分 &rpar;

    二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...

  4. Python之返回函数

    高阶函数可以把函数作为一个结果值返回 举例说明 普通的求积函数是 vim day5-6.py #!/usr/bin/python # -*- coding:utf-8 -*- def product( ...

  5. python 求解线性方程组

    Python线性方程组求解 求解线性方程组比较简单,只需要用到一个函数(scipy.linalg.solve)就可以了.比如我们要求以下方程的解,这是一个非齐次线性方程组: 3x_1 + x_2 - ...

  6. 【Mybatis】【1】generate批量生成实体类,数据库接口类和mapper

    前言: 1,实体类之类如果自己写的话,比较繁琐,还容易出错,所以用generate自动生成 2,int类型可能会生成为short类型,建议不要手动改回int类.因为下次生成又是short类型了,可能会 ...

  7. ubuntu 环境下的QT程序打包

    很多的时候 需要将自己写的QT 程序发布一下  所以今天教一下 怎么在ubuntu 环境下将自己的写的Qt 程序打包打包是为了不依赖 开发环境 和开发的库. 1. QtCreate使用Release版 ...

  8. Python - 常用更新命令以及常见库安装

    库的安装方式一般有两种: 一. pip直接安装(或使用豆瓣源) pip install scrapy pip install -i https://pypi.douban.com/simple/ sc ...

  9. MVC3学习:利用mvc3&plus;ajax结合MVCPager实现分页

    本例使用表格Users(Uid,UserName,PassWord),数据库访问使用EF first code. public class Users { [Key] public int Uid { ...

  10. Hbase 学习(八) 使用MapReduce

    在hbase的demo里面有个IndexBuilder的例子,它就是使用了MapReduce来操作hbase的,例子也比较简单,但是只包括了Mapper. 另外网上还有另外一个例子,也是说明这个的,这 ...