opencv识别数码管数字
一. 算法流程:
1)对图片进行缩放预处理的目的是为了模板匹配效果更优
Mat src_img = imread("./img/26.jpg", 1);Mat temp_img = imread("./img/temp1.jpg");Mat result_img;//先将原图进行缩放double d = 960.0 / src_img.rows;int w = src_img.cols * d;int h = src_img.rows * d;cv::resize(src_img, src_img, cv::Size(w, h));d = 300.0 / temp_img.rows;cv::resize(temp_img, temp_img, cv::Size(temp_img.cols * d, temp_img.rows * d));Mat temp_imgc = temp_img.clone();int temp_imgc_col = temp_img.cols - 1 * 0.05 * temp_img.cols;int temp_imgc_row = temp_img.rows - 1 * 0.05 * temp_img.rows;resize(temp_imgc, temp_imgc, Size(temp_imgc_col, temp_imgc_row));
2)模板匹配
//进行模板匹配matchTemplate(src_img, temp_imgc, result_img, 0);double minVal = -1;double maxVal;Point minLoc;Point maxLoc;Point matchLoc;minMaxLoc(result_img, &minVal, &maxVal, &minLoc, &maxLoc, Mat());Mat img_show = src_img.clone();matchLoc = minLoc;//根据resultImg中的最大值位置在源图上画出矩形rectangle(img_show, matchLoc, Point(matchLoc.x + temp_imgc.cols, matchLoc.y + temp_imgc.rows), Scalar(0, 255, 0), 1, 8, 0);imshow("ROI", img_show);
3)感兴趣区域
//获取匹配得到区域Rect roi = Rect(matchLoc, Point(matchLoc.x + temp_imgc.cols, matchLoc.y + temp_imgc.rows));Mat ROI_img = src_img.clone();ROI_img = ROI_img(roi);
4)转灰度图
//转灰度图cv::cvtColor(ROI_img, ROI_img, COLOR_RGB2GRAY);
5)二值化处理:变成黑白两色
//二值化,第三个参数根据实际情况动态调整threshold(ROI_img, ROI_img, 230, 255, THRESH_BINARY);
6)膨胀:将图片数字中有空隙的笔画变连贯
Mat dil_img;Mat element = getStructuringElement(MORPH_RECT, Size(10, 10)); // 膨胀dilate(ROI_img, dil_img, element);imshow("image_dil", dil_img);
7)轮廓提取:获取单个数字的矩形轮廓
//轮廓提取vector<vector<Point> > out;vector<Vec4i> hierarchy;cv::findContours(dil_img, out, hierarchy, RETR_LIST, CHAIN_APPROX_NONE);const size_t size = out.size();vector<Rect> num_location;for (int i = 0; i < size; i++){num_location.push_back(boundingRect(Mat(out[i])));// 转换为矩形轮廓}std::sort(num_location.begin(), num_location.end(), [](const cv::Rect& a, const cv::Rect& b) {if (a.x < b.x)return true;elsereturn false;});
8)数字分割和数字识别:分割成单个数字图片然后逐一识别
//数字分割for (int i = 0; i < size; i++){if (!IsAllWhiteOrBlack(dil_img(num_location[i]))) {//数字识别int num = TubeIdentification(dil_img(num_location.at(i)));std::cout << num << " ";}}
9)穿线法识别数字
算法原理:
如上图,将图片数字分成上下三等分、左右均分,然后分别判断a、b、c、d、e、f、g线条在六个空间里面的黑白像素占比,以此来判断该区域是否具有该线条,并且给每段线条赋予1、2、4、8、16、32、64的权值,通过累计权值,最后推导出数字。
bool Iswhite(const Mat& inputmat, int rowMin, int rowMax, int colMin, int colMax)
{int area = (colMax - colMin + 1) * (rowMax - rowMin + 1);Rect rect(colMin, rowMin, colMax - colMin + 1, rowMax - rowMin + 1);Mat roi = inputmat(rect);int total = cv::countNonZero(roi);if (total >= area * 1.0 / 5){return true;}return false;
}int TubeIdentification(Mat inputmat)
{int tube = 0;int tubo_roi[7][4] ={{ inputmat.rows * 0 / 3, inputmat.rows * 1 / 3, inputmat.cols * 1 / 2, inputmat.cols * 1 / 2 }, // a{ inputmat.rows * 1 / 3, inputmat.rows * 1 / 3, inputmat.cols * 2 / 3, inputmat.cols - 1 }, // b{ inputmat.rows * 2 / 3, inputmat.rows * 2 / 3, inputmat.cols * 2 / 3, inputmat.cols - 1 }, // c{ inputmat.rows * 2 / 3, inputmat.rows - 1 , inputmat.cols * 1 / 2, inputmat.cols * 1 / 2 }, // d{ inputmat.rows * 2 / 3, inputmat.rows * 2 / 3, inputmat.cols * 0 / 3, inputmat.cols * 1 / 3 }, // e{ inputmat.rows * 1 / 3, inputmat.rows * 1 / 3, inputmat.cols * 0 / 3, inputmat.cols * 1 / 3 }, // f{ inputmat.rows * 1 / 3, inputmat.rows * 2 / 3, inputmat.cols * 1 / 2, inputmat.cols * 1 / 2 }, // g};if (inputmat.rows / inputmat.cols > 2) // 1 is special, which is much narrower than others{tube = 6;}else{for (int i = 0; i < 7; i++){if (Iswhite(inputmat, tubo_roi[i][0], tubo_roi[i][1], tubo_roi[i][2], tubo_roi[i][3]))tube = tube + (int)pow(2, i);}}switch (tube){case 63: return 0; break;case 6: return 1; break;case 91: return 2; break;case 79: return 3; break;case 102: return 4; break;case 109: return 5; break;case 125: return 6; break;case 7: return 7; break;case 127: return 8; break;case 103:case 111: return 9; break;default: return -1;}
}
opencv识别数码管数字相关推荐
- 实战 | 计算器/数码管数字识别 基于OpenCV和EasyOCR/PaddleOCR(附源码)
点击下方卡片,关注"OpenCV与AI深度学习"公众号! 视觉/图像重磅干货,第一时间送达! 导读 本文主要介绍一个计算器显示数字识别的OCR实例,基于OpenCV和EasyOCR ...
- python信用卡识别_python opencv实现信用卡的数字识别
本项目利用python以及opencv实现信用卡的数字识别 前期准备 导入工具包 定义功能函数 模板图像处理 读取模板图像 cv2.imread(img) 灰度化处理 cv2.cvtColor(img ...
- 【实战】python以及opencv实现信用卡的数字识别
本项目利用python以及opencv实现信用卡的数字识别 前期准备 导入工具包 定义功能函数 模板图像处理 读取模板图像 cv2.imread(img) 灰度化处理 cv2.cvtColor(img ...
- 数码管数字识别方法整理
数码管数字识别方法整理 图像任务 OCR任务 图像分类 目标检测 图像分割 图像增强 视频任务 正文: OCR--数码管数字识别方法整理 文本检测+ 字符分割+ 单数字识别 参考资料: 参考博客: 参 ...
- OpenCV模板匹配识别图片中的数字
OpenCV模板匹配识别图片中的数字 前言 本博客主要实现利用OpenCV的模板匹配识别图像中的数字,然后把识别出来的数字输出到txt文件中,如果识别失败则输出"读取失败". 操作 ...
- 在OpenCV里使用SVM识别手写数字
前面使用了kNN算法来识别手写数字,我们是直接把数字的灰度值大小作为特征值来学习.而这里要使用SVM算法,是否也可以使用灰度值来做呢?对于SVM算法来说,可能要采用另外一个特征方式,叫做梯度方向直方图 ...
- 转载:使用 OpenCV 识别 QRCode
原文链接:http://coolshell.cn/articles/10590.html#jtss-tsina 识别二维码的项目数不胜数,每次都是开箱即用,方便得很. 这次想用 OpenCV 从零识别 ...
- opencv resize_利用OpenCV 识别两张相似的图片
Background: 在我们项目中,用到U-net,我们对训练样本图片使用labelme进行标定,对标定生成的json文件labelme_json_to_dataset生成标注图像,由于小伙伴将生成 ...
- opencv 取roi_利用OpenCV 识别两张相似的图片
Background: 在我们项目中,用到U-net,我们对训练样本图片使用labelme进行标定,对标定生成的json文件labelme_json_to_dataset生成标注图像,由于小伙伴将生成 ...
最新文章
- 【c语言】蓝桥杯入门训练 序列求和
- oracle乘法运算,oracle实现相乘话语
- 用P3P header解决IE下iframe跨域访问时候session丢失的问题
- 界面设计 java_Java界面设计
- 为减少用户电话排队,阿里研发了智能客服调度系统
- 服务提供商应该如何帮助企业保护数据安全
- Internationalization(i18n) support in SAP CRM,UI5 and Hybris
- 方程式漏洞之复现window2008/win7 远程命令执行漏洞
- 《JavaScript DOM编程艺术》笔记
- PyTorch系列入门到精通——模型创建与nn.Module
- C++11 Intro - Thread Id
- WP手机升级WIN10被PIN码锁定
- 抖音sdk,抖音开发api接口
- python输入用户名和密码_验证Python中的用户名和密码输入
- iOS 关于键盘监听
- MSDC 4.3 接口规范(14)
- SQL:开窗函数(窗口函数)
- 列车实时数据通信协议(TRDP)探索之路【三】
- 【c#】继承和多态的一点知识点
- CodeM资格赛D 送外卖 题解
热门文章
- C#上传图片至数据库
- k8s问题分析解决unable to recognize pet-set.yaml: no matches for kind PetSet in version apps/v1beta1
- “软硬结合”- 转转搜索少无结果模块简介
- Apple Pay出场带热NFC 国产手机厂商拥抱银联
- 每日一题,让你的代码也高大上起来
- CDMA EVDO 模块
- 信息比率(Information Ratio)
- 使用mob获取短信验证码
- 【算法】_008_归并排序_ 插入法优化
- 最近单位让草理的一个东西 软件包及其服务标准介绍