Java基于opencv实现图像数字识别(五)—投影法分割字符
Java基于opencv实现图像数字识别(五)—投影法分割字符
水平投影法
1、水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像);
2、选出一个最优的阀值,根据比这个阀值大或小,用一个数组记录相应Y轴的坐标;
3、因为是水平切割我们只需要Y轴的切割点即可,宽度默认图像的宽,高度可以用相邻的切割点相减得到;
4、优化切割点,把切割点靠近的都清除掉
5、设置感应区的区域,切割图片
垂直投影法和水平投影法类似,对比思考一下
因为我做的是表格的切割,你如果想实现验证码的切割,或者其他的类比这个,我想也是很容易实现的
我们先看一下,效果,还是很不错的

水平切割代码
// 图像切割,水平投影法切割
public List<Mat> cutImgX() {
int i, j;
int nWidth = getWidth(), nHeight = getHeight();
int[] xNum = new int[nHeight], cNum;
int average = 0;// 记录像素的平均值
// 统计出每行黑色像素点的个数
for (i = 0; i < nHeight; i++) {
for (j = 0; j < nWidth; j++) {
if (getPixel(i, j) == BLACK) {
xNum[i]++;
}
}
}
// 经过测试这样得到的平均值最优
cNum = Arrays.copyOf(xNum, xNum.length);
Arrays.sort(cNum);
for (i = 31 * nHeight / 32; i < nHeight; i++) {
average += cNum[i];
}
average /= (nHeight / 32);
// 把需要切割的y点都存到cutY中
List<Integer> cutY = new ArrayList<Integer>();
for (i = 0; i < nHeight; i++) {
if (xNum[i] > average) {
cutY.add(i);
}
}
// 优化cutY把
if (cutY.size() != 0) {
int temp = cutY.get(cutY.size() - 1);
// 因为线条有粗细,优化cutY
for (i = cutY.size() - 2; i >= 0; i--) {
int k = temp - cutY.get(i);
if (k <= 8) {
cutY.remove(i);
} else {
temp = cutY.get(i);
}
}
}
// 把切割的图片都保存到YMat中
List<Mat> YMat = new ArrayList<Mat>();
for (i = 1; i < cutY.size(); i++) {
// 设置感兴趣的区域
int startY = cutY.get(i - 1);
int height = cutY.get(i) - startY;
Mat temp = new Mat(mat, new Rect(0, startY, nWidth, height));
Mat t = new Mat();
temp.copyTo(t);
YMat.add(t);
}
return YMat;
}
垂直投影法
// 图像切割,垂直投影法切割
public List<Mat> cutImgY() {
int i, j;
int nWidth = getWidth(), nHeight = getHeight();
int[] xNum = new int[nWidth], cNum;
int average = 0;// 记录像素的平均值
// 统计出每列黑色像素点的个数
for (i = 0; i < nWidth; i++) {
for (j = 0; j < nHeight; j++) {
if (getPixel(j, i) == BLACK) {
xNum[i]++;
}
}
}
// 经过测试这样得到的平均值最优 , 平均值的选取很重要
cNum = Arrays.copyOf(xNum, xNum.length);
Arrays.sort(cNum);
for (i = 31 * nWidth / 32; i < nWidth; i++) {
average += cNum[i];
}
average /= (nWidth / 28);
// 把需要切割的x点都存到cutY中,
List<Integer> cutX = new ArrayList<Integer>();
for (i = 0; i < nWidth; i += 2) {
if (xNum[i] >= average) {
cutX.add(i);
}
}
if (cutX.size() != 0) {
int temp = cutX.get(cutX.size() - 1);
// 因为线条有粗细,优化cutY
for (i = cutX.size() - 2; i >= 0; i--) {
int k = temp - cutX.get(i);
if (k <= 10) {
cutX.remove(i);
} else {
temp = cutX.get(i);
}
}
}
// 把切割的图片都保存到YMat中
List<Mat> XMat = new ArrayList<Mat>();
for (i = 1; i < cutX.size(); i++) {
// 设置感兴趣的区域
int startX = cutX.get(i - 1);
int width = cutX.get(i) - startX;
Mat temp = new Mat(mat, new Rect(startX, 0, width, nHeight));
Mat t = new Mat();
temp.copyTo(t);
XMat.add(t);
}
return XMat;
}
注:本文章参考了很多博客,感谢;主要是跟着一个博客来实现的https://blog.csdn.net/ysc6688/article/category/2913009(也是基于opencv来做的)感谢
Java基于opencv实现图像数字识别(五)—投影法分割字符的更多相关文章
- Java基于opencv实现图像数字识别(五)—腐蚀、膨胀处理
腐蚀:去除图像表面像素,将图像逐步缩小,以达到消去点状图像的效果:作用就是将图像边缘的毛刺剔除掉 膨胀:将图像表面不断扩散以达到去除小孔的效果:作用就是将目标的边缘或者是内部的坑填掉 使用相同次数的腐 ...
- Java基于opencv实现图像数字识别(二)—基本流程
Java基于opencv实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ...
- Java基于opencv实现图像数字识别(四)—图像降噪
Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...
- Java基于opencv实现图像数字识别(三)—灰度化和二值化
Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...
- Java基于opencv实现图像数字识别(一)
Java基于opencv实现图像数字识别(一) 最近分到了一个任务,要做数字识别,我分配到的任务是把数字一个个的分开:当时一脸懵逼,直接百度java如何分割图片中的数字,然后就百度到了用Buffere ...
- Java基于opencv—矫正图像
更多的时候,我们得到的图像不可能是正的,多少都会有一定的倾斜,就比如下面的 我们要做的就是把它们变成下面这样的 我们采用的是寻找轮廓的思路,来矫正图片:只要有明显的轮廓都可以采用这种思路 具体思路: ...
- Java基于OpenCV实现走迷宫(图片+路线展示)
Java基于OpenCV实现走迷宫(图片+路线展示) 由于疫情,待在家中,太过无聊.同学发了我张迷宫图片,让我走迷宫来缓解暴躁,于是乎就码了一个程序出来.特此记录. 原图: 这张图,由于不是非常清晰, ...
- 基于Opencv快速实现人脸识别(完整版)
无耻收藏网页链接: 基于OpenCV快速实现人脸识别:https://blog.csdn.net/beyond9305/article/details/92844258 基于Opencv快速实现人脸识 ...
- java基于OpenCV的人脸识别
基于Java简单的人脸和人眼识别程序 使用这个程序之前必须先安装配置OpenCV详细教程见:https://www.cnblogs.com/prodigal-son/p/12768948.html 注 ...
随机推荐
- 菜鸟使用MySQL存储过程and临时表,供新手参考,请高手斧正
因为公司最近的一个项目,第一次用到了MySQL(5.10版本),之前听传说MySQL很厉害的样子,因为开源而神奇,但是现在用起来, 感觉并不好啊!我知道是我水平太down,呜呜呜,请各路神仙略施小技, ...
- Lambda为什么又称为匿名函数
用法: 有的类,里面只有一个方法,几行代码,只使用一次,以后再不会用到这个类,那就不值当的单独创建一个类,此时使用匿名内部类 一.传统方式 1.接口 2.接口实现类 创建一个类,这个类可能被多次使用, ...
- sed 命令总结
sed是Stream Editor的缩写,是操作.过滤.转换文本内容的强大工具,对文件实现增删改查 主要参数 -n 取消默认输出 -i 修改保存文件 内置命令字符 a,append追加 d,delet ...
- SQL-52 获取Employees中的first_name,查询按照first_name最后两个字母,按照升序进行排列
题目描述 获取Employees中的first_name,查询按照first_name最后两个字母,按照升序进行排列CREATE TABLE `employees` (`emp_no` int(11) ...
- LeakCanary 来检查 Android 内存泄漏
LeakCanary 来检查 Android 内存泄漏
- Linux下数据库备份
1.登录数据库服务器并切换到数据库用户下 [root@*** ~]# su - oracle 2.测试用户名密码是否能正确连接数据库 [oracle@*** ~]$ sqlplus username/ ...
- shell练习题2
需求如下: 写一个shell脚本,检查指定的shell脚本是否有语法错误,若有错误,首先显示错误信息,然后提示用户输入q或Q退出脚本, 输入其他内容则直接用vim打开该shell脚本. 参考解答如下 ...
- 利用 Eclipse IDE 的强大功能远程调试 Java 应用程序
II. Eclipse 连接套接字模式下的 VM 调用示例(具体引用实践) 说明:不管采用哪种方式,调试的源代码都在eclipse的环境下 一.调试方式一(将目标应用程序作为调试的服务器,eclips ...
- 简单理解 SVM
SVM,中文名叫支持向量机. 在深度学习出现以前,它是数据挖掘的宠儿: SVM具有十分完整的数据理论证明,但同时理论也相当复杂. 初识SVM 同其他分类算法一样,SVM分类也是寻找合适的决策边界,为 ...
- adaboost 参数选择
先看下ababoost和决策树效果对比 import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection ...