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 注 ...
随机推荐
- Ubuntu 18.04 下 Redis 环境搭建
一.安装 Redis ① 下载 wget http://download.redis.io/releases/redis-3.2.8.tar.gz ② 解压 tar -zxvf redis-3.2.8 ...
- 关于:无法创建链接服务器 "ORCL" 的 OLE DB 访问接口 "OraOLEDB.Oracle" 的实例 (错误:7302)
本人接触和使用Oracle数据库才有一个季度的时间,问题比较白,大神请无视本文. 环境: 1.数据服务器,windows2008R2,Oracle11g 2.报表服务器,windows2008R2,S ...
- java根据输入的字符串和字节数来截取,输出对应字节数的字符串
public class Test { //要进行截取操作的字符串 static String ss; //截取的字符串的字节数 static int n; public static void ma ...
- ansible 剧本
ansible的管理与剧本 首先我们安装一个ansible. 在7版本,直接用yum安装就可以 yum -y install ansible 然后清空ansible的配置文件,在里面写入自己需要管 ...
- Python爬虫入门之正则表达式
在前面我们已经搞定了怎样获取页面的内容,不过还差一步,这么多杂乱的代码夹杂文字我们怎样把它提取出来整理呢?下面就开始介绍一个十分强大的工具,正则表达式! 1.了解正则表达式 正则表达式是对字符串操作的 ...
- 指导手册 07 安装配置HIVE
指导手册 07 安装配置HIVE 安装环境及所需安装包: 1.操作系统:centos6.8 2.四台虚拟机:master :10.0.2.4, slave1:10.0.2.5,slave2:10. ...
- 三元运算和bytes数据类型笔记
三元运算 result = 值1 if条件 else 值2 如果条件为真:result = 值1 如果条件为假:result = 值2 bytes数据类型 字符串可以编码成字节包,字节包也可以解码成 ...
- @EnableHystrix
@EnableHystrix 启动熔断降级服务 @Component把普通的pojo类实例到spring容器中去,相当于配置文件中的<bean id="" class=&qu ...
- Android 面试100问- 0序0
准备找android方面的工作,现收集面试题,打算收集100个并记录
- Quartz 2.2 动态添加、修改和删除定时任务
QuartzManager.Java 动态添加.修改和删除定时任务管理类 import org.quartz.CronScheduleBuilder; import org.quartz.CronTr ...