在今年泰迪杯A题电商中图片的文字识别这道题中,我们先用了一种很笨的办法来分割字符。
首先对图片进行灰度化,然后二值化,这里的二值化要选择一个合适的阈值。然后我们进行轮廓的提取,计算轮廓最小矩形的面积,若面积过大,则认为这个是背景图片,若面积过小,则认为是噪点。这种方法有一个弊端,就是文字有大有小,大的文字也有可能会被当成背景,小的标点也可能会被当成噪点。

代码如下:
实现了读入一张图片,进行灰度化,二值化,分割字符,输出字符.jpg到指定位置,以及输出字符最小矩形的坐标。

 const string imagename = "1.jpg";    //此处需要填写绝对地址,我测试时使用相对地址出错。
//读入图像
Mat img = imread(imagename);
//如果读入图像失败
if (img.empty())
{
return -1;
} int Hmin = 0, Hmax = 156;
int AreaMin = 15, AreaMax = 135;
int Area = 200;
//创建窗口
cv::namedWindow("thresh");
cv::createTrackbar("Hmin", "thresh", &Hmin, 255, NULL); cv::createTrackbar("Hmax", "thresh", &Hmax, 255, NULL);
cv::createTrackbar("AreaMin", "thresh", &AreaMin, 200, NULL);
cv::createTrackbar("AreaMax", "thresh", &AreaMax, 200, NULL);
cv::createTrackbar("Area", "thresh", &Area, 4000, NULL);
for (;;){
int _Hmin = Hmin, _Hmax = Hmax;
int _AreaMin = AreaMin, _AreaMax = AreaMax;
Mat HSV, thresh, GRAY,gray,src;
//vector<Mat> channels;
cvtColor(img, GRAY, CV_BGR2GRAY);
//cvtColor(img, HSV, CV_BGR2HSV);
//CV_BGR2GRAY转为灰度 CV_BGR2HSV转为HSV CV_BGR2YUV转为YUV CV_BGR2YCrCb转为YCrCb
//split(HSV, channels);
// channels[2]=0;
inRange(GRAY,
cv::Scalar(MIN(_Hmin, _Hmax), MIN(0, 255), MIN(0, 255)),
cv::Scalar(MAX(_Hmin, _Hmax), MAX(0, 255), MAX(0, 255)), //scalar 中 (b,g,r,0) 即bgr 而非 rgb
thresh);//color
gray = GRAY;
thresh = 255 - thresh;
//cvShowImage("ThresholdImg", GRAY); dilate(thresh, thresh, NULL, cv::Point(-1, -1), 30);
erode(thresh, thresh, NULL, cv::Point(-1, -1), 30); cv::imshow("thres", thresh);
cv::waitKey(1);
vector<cv::vector<cv::Point> > contours;
vector<cv::Vec4i> hierarchy;
// 找出图像中的最大轮廓
findContours(thresh, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
// 定义一个 Rect 矢量来存放轮廓。因为轮廓的外形多数时候是不规则的。所以用一个矩形来代替 不规则的轮廓会在各种方面都方便很多。
//printf("轮廓个数:%d", contours.size());
cv::vector<cv::vector<cv::Point> > contours_poly(contours.size());
cv::vector<cv::Rect> boundRect(contours.size()); cv::vector<cv::Point2f>center(contours.size());
cv::vector<float>radius(contours.size());
int maxArea = 0;
int index = 0;
int minArea = 50;
int ci = 0;
for (unsigned int i = 0; i<contours.size(); i++)
// 用一个 for 循环语句查看计算机找到的全部轮廓
{
int area = contourArea(contours[i]);// 计算当前轮廓的包含面积
if (area> maxArea) // 找出包含面积最大的轮廓
{
maxArea = area;
index = i;
} if (area<_AreaMax&&area>_AreaMin)
{
ci++;
approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 3, true);
// approxPolyDP() 用来找出轮廓的近似多边形。用于简化轮廓的复杂度,加速计算过程。 boundRect[i] = cv::boundingRect(cv::Mat(contours_poly[i]));
//BoundingRect() 是一个用来找出轮廓最小包围矩形函数。
//最小包围矩形的意思就是用 4 条边从 上下左右四个方向把轮廓紧紧夹在中间。这 4 条边构成的矩形就是最小包围矩形。 //drawContours(img, contours, i, CV_RGB(255, 255, 255), 1, 8, hierarchy, 0, cv::Point()); // 画出物体的轮廓 rectangle(GRAY, boundRect[i].tl(), boundRect[i].br(), CV_RGB(255, 0, 0), 2, 8, 0); // 画出物体的最小包围矩形
// 矩形的自然就是 boundRect() 算出的轮廓。
//printf("左上角x坐标:%d左上角y坐标:%d ", boundRect[i].tl().x, boundRect[i].tl().y);
//printf("右下角x坐标:%d右下角y坐标:%d ", boundRect[i].br().x,boundRect[i].br().y);
printf("PA%dPA %d %d %d %d\n",i,boundRect[i].tl().x, boundRect[i].br().y, boundRect[i].br().x, boundRect[i].tl().y);
//printf("左下角x坐标:%d左下角y坐标:%d 右上角x坐标:%d右上角y坐标:%d ", boundRect[i].tl().x, boundRect[i].br().y, boundRect[i].br().x, boundRect[i].tl().y);
Mat imgROI = img(Rect(boundRect[i].tl().x, boundRect[i].tl().y, std::abs(boundRect[i].br().x - boundRect[i].tl().x), std::abs(boundRect[i].br().y - boundRect[i].tl().y)));
CString _file;
_file.Format("./test/%d.jpg", i+1);
std::string path = _file;
imwrite(path, imgROI);
} } //printf("字数:%d", ci);
//imshow("HSV", HSV); imshow("GRAY", GRAY);
//创建窗口
//显示图像
// namedWindow("SRC", 1);
imshow("img", img);
CString _file;
_file.Format("gray.jpg");
std::string path = _file;
imwrite(path, GRAY);
// imshow("it", thresh);
//等待按键,按键盘任意键返回
waitKey(0);
}

【OpenCV】一种基于阈值的图片中的文字分割的更多相关文章

  1. C# 图片识别技术(支持21种语言,提取图片中的文字)

    图片识别的技术到几天已经很成熟了,只是相关的资料很少,为了方便在此汇总一下(C#实现),方便需要的朋友查阅,也给自己做个记号. 图片识别的用途:很多人用它去破解网站的验证码,用于达到自动刷票或者是批量 ...

  2. OpenCV几种边缘检测的简例

    简单记录一下OpenCV的几种边缘检测函数的用法. 边缘检测算法 以Sobel边缘检测算法为例. Sobel卷积核模板为: 偏导公式为: Gx(i,j)=[f(i+1,j−1)+2f(i+1,j)+f ...

  3. [信安Presentation]一种基于GPU并行计算的MD5密码解密方法

    -------------------paper--------------------- 一种基于GPU并行计算的MD5密码解密方法 0.abstract1.md5算法概述2.md5安全性分析3.基 ...

  4. <<一种基于δ函数的图象边缘检测算法>>一文算法的实现。

    原始论文下载: 一种基于δ函数的图象边缘检测算法. 这篇论文读起来感觉不像现在的很多论文,废话一大堆,而是直入主题,反倒使人觉得文章的前后跳跃有点大,不过算法的原理已经讲的清晰了.     一.原理 ...

  5. 16种基于 CSS3 & SVG 的创意的弹窗效果

    在去年,我给大家分享了<基于 CSS3 的精美模态窗口效果>,而今天我要与大家分享一些新鲜的想法.风格和趋势变化,要求更加适合现代UI的不同的效果.这组新模态窗口效果包含了一些微妙的动画, ...

  6. tmpfs:一种基于内存的文件系统

    tmpfs是一种基于内存的文件系统, tmpfs有时候使用rm(物理内存),有时候使用swap(磁盘一块区域).根据实际情况进行分配. rm:物理内存.real memery的简称? 真实内存就是电脑 ...

  7. 一种基于重载的高效c#上图片添加文字图形图片的方法

    在做图片监控显示的时候,需要在图片上添加文字,如果用graphics类绘制图片上的字体,实现图像上添加自定义标记,这种方法经验证是可行的,并且在visual c#2005 编程技巧大全上有提到,但是, ...

  8. 一种基于Qt的可伸缩的全异步C/S架构服务器实现(流浪小狗,六篇,附下载地址)

    本文向大家介绍一种基于Qt的伸缩TCP服务实现.该实现针对C/S客户端-服务集群应用需求而搭建.连接监听.数据传输.数据处理均在独立的线程池中进行,根据特定任务不同,可安排负责监听.传输.处理的线程数 ...

  9. 一种基于Qt的可伸缩的全异步C/S架构server实现(一) 综述

    本文向大家介绍一种基于Qt的伸缩TCP服务实现.该实现针对C/Sclient-服务集群应用需求而搭建. 连接监听.传输数据.数据处理均在独立的线程池中进行,依据特定任务不同,可安排负责监听.传输.处理 ...

随机推荐

  1. 支持向量机SVM(一)

    [转载请注明出处]http://www.cnblogs.com/jerrylead 1 简介 支持向量机基本上是最好的有监督学习算法了.最开始接触SVM是去年暑假的时候,老师要求交<统计学习理论 ...

  2. html5获取用户当前的地理位置,即经纬度。

    $("document").ready(function(){ getMap(); }); function getMap(){ // 百度地图API功能 var map = ne ...

  3. java使用spark/spark-sql处理schema数据(spark1.6)

    1.spark是什么? Spark是基于内存计算的大数据并行计算框架. 1.1 Spark基于内存计算 相比于MapReduce基于IO计算,提高了在大数据环境下数据处理的实时性. 1.2 高容错性和 ...

  4. 全球多个 TOP 网站藏挖矿代码,5 亿 PC 沦为矿工

    据ZDNet报道,现在很多网站都开始在网页脚本中藏匿挖矿代码,在用户访问时偷算力用于挖矿.来自Adguard的报告称也证实,也有5亿台电脑中招. 最新最热的IT技术付费社区 IT帮 itbang.me ...

  5. CoreData归纳使用

    1.CoreData简介 2.CoreData数据模型 3.CoreData的主要对象 4.使用CoreData实现数据存储 一.CoreData简介 CoreData用做数据持久化,是数据持久化的最 ...

  6. 初识SQL Server2017 图数据库(一)

    背景: 图数据库对于表现和遍历复杂的实体之间关系是很有效果的.而这些在传统的关系型数据库中尤其是对于报表而言很难实现.如果把传统关系型数据库比做火车的话,那么到现在大数据时代,图数据库可比做高铁.它已 ...

  7. 使用Xshell5连接虚拟机VMware中安装的CentOS7系统

    使用Xshell5连接VMware中安装的CentOS7系统 准备材料 Xshell 下载地址 VMware Workstation 12 Pro 下载地址 CentOS 7 64位系统 下载地址 安 ...

  8. 转:C++输入一行字符串的一点小结

    原文链接: http://www.wutianqi.com/?p=1181 大家在学习C++编程时,一般在输入方面都是使用的cin.而cin是使用空白(空格,制表符和换行符)来定字符串的界的.这就导致 ...

  9. 【转】话说C语言const用法

    原文:话说C语言const用法 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修 ...

  10. MySql 5.7.20安装

    1.首先上MySql的官网下载  https://dev.mysql.com/downloads/mysql/ 以我所选版本为例(免安装版),选择MYSQL Community Server 然后在右 ...