基于Opencv实现的简易汉字识别

您所在的位置:网站首页 图像识别是如何实现的 基于Opencv实现的简易汉字识别

基于Opencv实现的简易汉字识别

2024-07-12 07:06| 来源: 网络整理| 查看: 265

使用C++结合Opencv库实现简易汉字识别。

文章目录 Opencv实现汉字识别程序实现思路图像预处理思路实现实例 对比方法模型训练识别过程 特殊参数使用说明模型训练模型导入汉字识别 程序使用结果不足以及思考

Opencv实现汉字识别 程序实现思路 图像预处理

导入图像进行一系列预处理,使其便于用来识别和其他计算。

思路

灰度化

使用opencv的库函数来实现。

cv::cvtColor(image, image_gray, CV_BGR2GRAY);

二值化

同样选用库函数来实现,本例使用的是自适应二值化函数。

cv::adaptiveThreshold(image_gray, image_value, 255, 0, 1, 5, 10);

降噪(去除干扰线)

实现的思路并非去除干扰线,而是尽量不把干扰线选中到识别区域。

先通过腐蚀,使较细的干扰线消去。

erode(image_value, temp, kernel2);

再通过膨胀,使汉字主体明显。

dilate(temp, dst, kernel1);

轮廓识别

使用库函数找出外轮廓点集。

findContours(dst, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point());

最小矩阵

使用库函数找出包含轮廓点集的最小矩形。将其画出。

汉字分割

将矩阵框出的部分,复制到新的Mat数组中。 实现实例

准备一张用于当作模型的图片。 在这里插入图片描述

灰度化

在这里插入图片描述

本身就只有大部分为黑白色,故灰度化结果不明显。

二值化

在这里插入图片描述

腐蚀 在这里插入图片描述

可以发现干扰线已经基本看不见了,但是汉字好似被断裂开。不利于后面的寻找轮廓,故进行膨胀操作。

膨胀

在这里插入图片描述

膨胀有两个目的:一是使腐蚀后断裂的文字合起来。二是使某些上下结构或左右结构明显的字合起来。否则在识别(吴)的区域时,容易将(口)(天)分别框出,不利于识别整体的汉字。

最小矩阵

在膨胀后的基础上,寻找轮廓,并找出轮廓的最小矩阵。 在这里插入图片描述

切割后保存

框出文字的矩阵只在测试时画出,实际裁剪保存的时候,并不绘制出矩阵,是为了排除矩阵的存在对识别精确度的影响。

在这里插入图片描述

分割后保存的模板

对比方法

本例使用直方图匹配的方式,此方式的精确度实际并不高。其他如卷积神经网络难度较大,暂时没有足够的时间研究。故采用此种方法。

主要是将c。三者关系一一对应。找出与识别对象的直方图数据匹配图最高的模板图像,就可以确定其文字。

模型训练

模板图像——直方图数据——汉字

采用结构体。

struct pimage { char c_name[3]; Mat img_zft; };

从模板数据库中,读取每张文字对应的图片。将其灰度化后,计算直方图数据。

本例的数据都没有采用写入到文件的方式保存,故每次运行前都要导入一次模型,用于计算这些数据。

数据关联

for (i = 0; i < num; i++) { //直方图计算 calcHist(&imgNo_gray[i], 1,&channels ,Mat(), hist[i], 1, &histSize,&phranges_arr); strcpy_s(p_imgNo[i].c_name, img_word[i]);//手写字关联 p_imgNo[i].img_zft = hist[i];//直方图关联 } 识别过程

完成上面的模型制作,以及数据关联后。就可以进行识别过程了。

先进行预处理过程,再同样计算直方图。和模型数据进行对比。

double Compare,compare; int word = 0; for (int j = 0; j < contours.size()-1; j++) { if (contours[j].size() < 10) { word++; continue; } compare = 0; for (int k = 0; k < num; k++) { //使用CV_COMP_CORREL方法进行对比 Compare = compareHist(hist1[j], p_imgNo[k].img_zft, 0); //精准度达90% if (Compare >= 0.9) { if (compare > Compare) { continue; } else { compare = Compare; strcpy_s(p_img[j].c_name, p_imgNo[k].c_name); } } } } //识别完成,输出结果 printf_s("检测到%d个文字,分别是\n",contours.size()-word); for (int i = 0; i < contours.size(); ++i) { cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3