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实现图像数字识别(五)—投影法分割字符的更多相关文章

  1. Java基于opencv实现图像数字识别(五)—腐蚀、膨胀处理

    腐蚀:去除图像表面像素,将图像逐步缩小,以达到消去点状图像的效果:作用就是将图像边缘的毛刺剔除掉 膨胀:将图像表面不断扩散以达到去除小孔的效果:作用就是将目标的边缘或者是内部的坑填掉 使用相同次数的腐 ...

  2. Java基于opencv实现图像数字识别(二)—基本流程

    Java基于opencv实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ...

  3. Java基于opencv实现图像数字识别(四)—图像降噪

    Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...

  4. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  5. Java基于opencv实现图像数字识别(一)

    Java基于opencv实现图像数字识别(一) 最近分到了一个任务,要做数字识别,我分配到的任务是把数字一个个的分开:当时一脸懵逼,直接百度java如何分割图片中的数字,然后就百度到了用Buffere ...

  6. Java基于opencv—矫正图像

    更多的时候,我们得到的图像不可能是正的,多少都会有一定的倾斜,就比如下面的 我们要做的就是把它们变成下面这样的 我们采用的是寻找轮廓的思路,来矫正图片:只要有明显的轮廓都可以采用这种思路 具体思路: ...

  7. Java基于OpenCV实现走迷宫(图片+路线展示)

    Java基于OpenCV实现走迷宫(图片+路线展示) 由于疫情,待在家中,太过无聊.同学发了我张迷宫图片,让我走迷宫来缓解暴躁,于是乎就码了一个程序出来.特此记录. 原图: 这张图,由于不是非常清晰, ...

  8. 基于Opencv快速实现人脸识别(完整版)

    无耻收藏网页链接: 基于OpenCV快速实现人脸识别:https://blog.csdn.net/beyond9305/article/details/92844258 基于Opencv快速实现人脸识 ...

  9. java基于OpenCV的人脸识别

    基于Java简单的人脸和人眼识别程序 使用这个程序之前必须先安装配置OpenCV详细教程见:https://www.cnblogs.com/prodigal-son/p/12768948.html 注 ...

随机推荐

  1. git(三) 使用github

    1.创建仓库 ① 注册github账户,登录后,点击"New respository ". ② 在新页面中,输入项目的名称,勾选'readme.md',点击'create repo ...

  2. 为虚机Linux系统设置静态IP,ping通外网并解决相关问题

    在虚机中安装完Linux系统后,虚机是ping不通外网的,而默认的动态IP会为之后的Hadoop应用造成不少麻烦,为了减少这些不必要的麻烦,我们把系统的IP设置为静态. 步骤: 修改系统配置文件 命令 ...

  3. 三星I939D手机刷机记录

    三星I939D刷机经过 2017.10.21 ===================== 之前手机的Recovery已经升级过了. 由于一直没有找到原版的升级包,而网上的升级包几乎没有一个干净的,垃圾 ...

  4. Kostya Keygen#2分析

    主要就是构造408ede处的2A个字节.. 其中第一个字节必须为0x2D,倒数第二个字节必须为0x36,倒数第三个字节为0x31. 之后,对这个2A字节的缓冲区,要满足一些条件: 1\ 在408ede ...

  5. abap将内表数据导出为excel文件

    一个不错的方案: WHEN 'EXPORT'. "导出数据 DATA : GT_TEMP TYPE TABLE OF TY_ITEM WITH HEADER LINE. LOOP AT GT ...

  6. SSM中的Mybatis的操作

    一:整合日志含有log4j和logback logback是log4j的升级版他性能提升较大,有些甚至达到10倍以上,占的内存更小,slf4j能很好的整合它,还有很多数不胜数的优势 1.下载jar包, ...

  7. 4ci

  8. 【转载】安装 gephi 软件

    作者:小小爽链接:https://www.zhihu.com/question/21268129/answer/354924066来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  9. SSM搭建遇到的坑

    1,Error:(6, 24) java: package org.junit.runner does not exist 错误原因: 当时傻傻的把zl 包(单元测试包)放在了src/main/jav ...

  10. nopcommerce 4.1 core 学习 增加商城配置属性

    需求:  原本是想用nop 来做国际版的商城,可以像亚马逊那样 国内外通用,  专门增加一个跨进元素属性. 学习里面的一些架构思想.  国内的行情还是 像himall  会比较实用. 这是在商城的综合 ...