也是刚学opencv,参考一些资料,完成简单的数字匹配;

#pragma once
#include <iostream>
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <boost/shared_array.hpp>
#include <opencv2/imgproc/types_c.h>
#include <boost/format.hpp>
#include <math.h>
#include <vector>
#include <map>
using namespace  cv;
using namespace  std;class NumModule
{
public:NumModule(int num);NumModule();virtual ~NumModule();bool MatchImg(Mat &src);bool MatchImgHuSrcModel(Mat &srcimg, Mat &modelimg);
private:bool  GetImg();Point getNextMaxLoc(Mat &img, Point maxLoc, double minValue, int templatW, int templatH);bool  Printdigit();void  GetContourCoordinate(Mat &img, vector<vector<Point>>&contour);
private:int m_dnum;string strTmppath;vector<Mat>m_vecimg;map<int,int> m_mapdata;
};
#include "NumModule.h"NumModule::NumModule()
{}NumModule::NumModule(int num):m_dnum(num)
{strTmppath = "./Image/Work/Test6/";m_vecimg.clear();m_mapdata.clear();
}NumModule::~NumModule()
{}
/*----------------------------------------------------------------
* Function :GetImg
* Description :获取模板的img
* Param  :
* Output :
* Return :bool
* Author :
* Date :2022/02/10
/----------------------------------------------------------------*/
bool NumModule::GetImg()
{string path = "";for (int i=0;i< m_dnum;i++){path = strTmppath + to_string(i) + ".jpg";Mat tmp = imread(path);if (!tmp.data){cout << path << "is not exist!" << endl;return false;}//灰度化----阈值化Mat  tempgray, tempthres;cvtColor(tmp, tempgray, CV_BGR2GRAY);threshold(tempgray, tempthres, 128, 255, THRESH_BINARY | THRESH_OTSU);m_vecimg.push_back(tempthres);}return true;
}
/*----------------------------------------------------------------
* Function :getNextMaxLoc
* Description :得到下一个匹配度高的数字坐标
* Param  :Mat &img, Point maxLoc, double minValue, int templatW, int templatH
* Output :
* Return :Point
* Author :cyf
* Date :2022/02/10
/----------------------------------------------------------------*/
Point NumModule::getNextMaxLoc(Mat &img, Point maxLoc, double minValue, int templatW, int templatH)
{//设置开始寻找的位置,同时为多次进入函数 不检测之前的坐标int startX = maxLoc.x - templatW;int startY = maxLoc.y - templatH;int endX = maxLoc.x + templatW;int endY = maxLoc.y + templatH;//卡控if (startX < 0 || startY < 0){startX = startY = 0;}if (endX > (img.cols - 1) || endY > (img.rows - 1)){endX = img.cols - 1;endY = img.rows - 1;}//替换为最小值,因为采用了 使用归一化系数匹配,1是匹配度最高的for (int y = startY; y < endY; y++){for (int x = startX; x < endX; x++){//cvSetReal2D(&img, y, x, maxValue);float *data = img.ptr<float>(y);data[x] = minValue;}}double new_minValue, new_max_Value;Point new_minLoc, new_maxLoc;minMaxLoc(img, &new_minValue, &new_max_Value, &new_minLoc, &new_maxLoc);//imshow("result_end", img);return new_maxLoc;
}
/*----------------------------------------------------------------
* Function :MatchImg
* Description :匹配多个对象
* Param  :src
* Output :
* Return :
* Author :
* Date :2022/02/10
/----------------------------------------------------------------*/
bool NumModule::MatchImg(Mat &src)
{do {//灰度化----阈值化Mat srcgray, srcthres;cvtColor(src, srcgray, CV_BGR2GRAY);threshold(srcgray, srcthres, 128, 255, THRESH_BINARY | THRESH_OTSU);//得到模板图像if (!GetImg())return false;for (int i = 0; i < m_vecimg.size(); i++){Mat temp = m_vecimg[i].clone();if (temp.empty()){cout << "子图像不存在" << endl;break;}//设置结果图的尺寸,根据Opencv的公式int srcW, srcH, templatW, templatH, resultH, resultW;srcW = src.cols;srcH = src.rows;templatW = temp.cols;templatH = temp.rows;if (srcW < templatW || srcH < templatH){cout << "模板不能比原图大" << endl;break;}//设置输出图的大小,opencv公式计算Mat result;resultW = srcW - temp.cols + 1;resultH = srcH - temp.rows + 1;double minValue, maxValue;Point minLoc, maxLoc;result.create(Size(resultW, resultH), CV_32FC1);//模板匹配,使用归一化系数匹配matchTemplate(srcthres, m_vecimg[i], result, TM_CCOEFF_NORMED);//计算输出图中 的 最大最小值,和相应的坐标minMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc);//建立循环,多目标匹配float *data = result.ptr<float>(maxLoc.y);vector<Point> mveccoordinate;while (data[maxLoc.x] > 0.9){mveccoordinate.push_back(maxLoc);maxLoc = getNextMaxLoc(result, maxLoc, minValue, templatW, templatH);data = result.ptr<float>(maxLoc.y);}for (size_t k = 0; k < mveccoordinate.size(); k++){//rectangle(src, cv::Rect(mveccoordinate[k].x, mveccoordinate[k].y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);//m_mapdata.insert(mveccoordinate[k].x, i);m_mapdata[mveccoordinate[k].x] = i;}}Printdigit();return true;} while (0);return false;
}
/*----------------------------------------------------------------
* Function :Printdigit
* Description : 输出匹配的数字
* Param  :
* Output :
* Return :bool
* Author :
* Date :2022/02/10
/----------------------------------------------------------------*/
bool  NumModule::Printdigit()
{do {if (m_mapdata.empty()){cout << "待检测的图中没有匹配到数字" << endl;break;}//方法1for (auto it:m_mapdata){cout << it.second;}//方法3/*for_each(m_mapdata.begin(), m_mapdata.end(), [](map<int,int>::reference a){cout << a.second;});*///方法2
/*         auto it = m_mapdata.cbegin();
//         while (it!=m_mapdata.cend())
//         {
//             cout << it->second;
//             it++;}*/ cout << endl;} while (0);return false;
}/*----------------------------------------------------------------
* Function ;MatchImgHuSrcModel
* Description :利用HU矩 模板匹配.
* Param  :
* Output :
* Return :
* Author :
* Date :2022/03/08
/----------------------------------------------------------------*/
bool NumModule::MatchImgHuSrcModel(Mat&src, Mat &modelimg)
{Mat srcgray, srcbinary;Mat modelimggray, modelimgbinary;vector<vector<Point>> srccontours, modelcontours;//转换为灰度图cvtColor(src, srcgray, CV_BGR2GRAY);cvtColor(modelimg, modelimggray, CV_BGR2GRAY);//转换为二值化图threshold(srcgray, srcbinary, 128, 255, THRESH_BINARY | THRESH_OTSU);threshold(modelimggray, modelimgbinary, 128, 255, THRESH_BINARY | THRESH_OTSU);bitwise_not(srcbinary, srcbinary);bitwise_not(modelimgbinary, modelimgbinary);//获取轮廓GetContourCoordinate(srcbinary, srccontours);GetContourCoordinate(modelimgbinary, modelcontours);//模板Moments mm2 = moments(modelcontours[0]);Mat hu2;HuMoments(mm2, hu2);for (int i=0; i< srccontours.size();i++){Moments mm = moments(srccontours[i]);Mat hum;HuMoments(mm, hum);//Hu矩匹配double dis = matchShapes(hum, hu2, CONTOURS_MATCH_I1, 0);if (dis<8){drawContours(src, srccontours, i, Scalar(255, 0, 0), 2, LINE_AA);}}imshow("result", src);return 0;
}/*----------------------------------------------------------------
* Function ;GetContourCoordinate
* Description : 获取指定图片的轮廓坐标
* Param  :
* Output :
* Return :
* Author :
* Date :2022/03/08
/----------------------------------------------------------------*/
void NumModule::GetContourCoordinate(Mat &img, vector<vector<Point>>&contours)
{vector<Vec4i>hierarchy;findContours(img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
}
#include "NumModule.h"void main()
{cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_SILENT);//opencv   直方图 匹配并打印所有的数字 Mat src = imread("./Image/Work/Test6/Test6.png");if (src.empty()){cout << "can't find ./Image/Work/Test6/Test6.png" << endl;return;}imshow("src", src);NumModule nmodule(10);nmodule.MatchImg(src);waitKey(0);system("pause");return;
}

需要检测的数字和模板:


测试结果如下:

opencv 使用直方图匹配数字相关推荐

  1. 基于OpenCV的直方图匹配

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 如何为图像生成直方图,如何使直方图相等,最后如何将图像直方图修改为 ...

  2. c++ opencv 图像处理:直方图处理(直方图均衡化,直方图匹配(规定化))

    文章目录 前言 一.直方图(histogram) 二.直方图处理 1.直方图均衡化 2.直方图匹配(规定化) 三.opencv函数总结 1.equalizeHist图像均衡化 2.calcHist获取 ...

  3. 在OpenCV下写的直方图匹配(直方图规定化)C++源码!

    直方图匹配的原理就不多作解释了,我曾经还将MATLAB源码改写成过C源码,详情可见我的博文 根据MATLAB的histeq函数改写的运行在OpenCV下的直方图规定化C源码! 本文已转移到 https ...

  4. 【OpenCV】直方图应用:直方图均衡化,直方图匹配,对比直方图

    本文链接:https://blog.csdn.net/xiaowei_cqu/article/details/7606607                                       ...

  5. 第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波9 - 直方图处理 - 直方图匹配(规定化)灰度图像,彩色图像都适用

    直方图匹配(规定化) 连续灰度 s=T(r)=(L−1)∫0rpr(w)dw(3.17)s = T(r) = (L-1) \int_{0}^{r} p_r(w) \text{d} w \tag{3.1 ...

  6. 【OpenCV 例程200篇】48. 图像增强—彩色直方图匹配

    [OpenCV 例程200篇]48. 图像增强-彩色直方图匹配 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 图像直 ...

  7. 【OpenCV 例程200篇】47. 图像增强—直方图匹配

    [OpenCV 例程200篇]47. 图像增强-直方图匹配 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 图像直方图 ...

  8. OpenCV学习(二十) :直方图匹配、对比:calcHist(),minMaxLoc(),compareHist()

    直方图匹配.对比:calcHist ,minMaxLoc,compareHist 1.calcHist()函数 2.归一化:normalize()函数 3.minMaxLoc()函数 4.compar ...

  9. C++版本OpenCv教程(二十四)直方图匹配

    直方图均衡化函数可以自动的改变图像直方图的分布形式,这种方式极大的简化了直方图均衡化过程中需要的操作步骤,但是该函数不能指定均衡化后的直方图分布形式.在某些特定的条件下需要将直方图映射成指定的分布形式 ...

最新文章

  1. 【OpenCV】使用过的函数汇总
  2. atitti.atiNav 手机导航组件的设计
  3. Socket,非阻塞,fcntl
  4. Spring Security构建Rest服务-0100-前言
  5. 火狐浏览器title过长显示不全_浏览器渲染
  6. camera (14)---智能手机双摄像头原理解析:RGB +Depth
  7. 20155311高梓云的随笔
  8. 前端练手项目合集40.0个,附源码,2022年最新
  9. Jacoco 实现 Android 端手工测试覆盖率统计
  10. KYLO的Spring知识总结
  11. vue cl3、vuex、vue-router、ant design vue、axios搭建一个简易的单页面应用
  12. 夏普PC_1500计算机使用,夏普PC-1500袖珍计算机的检修(续)
  13. 计算机研究生个人简历,美国计算机研究生申请个人简历这样填比模板更出众!...
  14. [MQ]消息队列与企业服务总线的简单比较,MQESB
  15. 2020-09-15,小米笔试,java
  16. ArcGIS之创建企业级地理数据库(Oracle)
  17. AWS中国 Kubernetes 搭建指南
  18. JAVA基础Day01
  19. Bootstrap导航条学习使用(一)
  20. 《java并发编程实战》读书笔记二 对象的发布与逸出

热门文章

  1. SpringBoot 配置支付宝接口
  2. iOS 地图定位 地图
  3. oracle中怎么获取系统时间,oracle中得到当前系统时间
  4. 如何实现一个虚拟路由器(2)
  5. GDI+学习之线性渐变画刷
  6. Android开发-手机适配之dimen
  7. shopping计算器
  8. 【Python】数组整列赋值问题
  9. Linux如何获取打印机驱动将发送到打印机的数据?
  10. 【STM32】EXTI