由于要做图像的处理,所以最近在学习Opencv的相关知识,学习了Opencv中的Mat对象,查阅了网上的资料,了解了相关知识。现在实现了一个使用Mat对象来进行图像的水平投影与垂直投影,并在此基础之上,实现了字符的切分。现在将相关代码贴出,一来可以供大家参考并指正错误,而来也为的是防止忘记了相关知识。以下就是程序的代码,欢迎大家指正错误。

#include

#include "opencv2/imgproc/imgproc.hpp"

#include "opencv2/highgui/highgui.hpp"

#include

#include

using namespace cv;

using namespace std;

vector horizontalProjectionMat(Mat srcImg)//水平投影

{

Mat binImg;

blur(srcImg, binImg, Size(3, 3));

threshold(binImg, binImg, 0, 255, CV_THRESH_OTSU);

int perPixelValue = 0;//每个像素的值

int width = srcImg.cols;

int height = srcImg.rows;

int* projectValArry = new int[height];//创建一个储存每行白色像素个数的数组

memset(projectValArry, 0, height * 4);//初始化数组

for (int col = 0; col < height; col++)//遍历每个像素点

{

for (int row = 0; row < width; row++)

{

perPixelValue = binImg.at(col, row);

if (perPixelValue == 0)//如果是白底黑字

{

projectValArry[col]++;

}

}

}

Mat horizontalProjectionMat(height, width, CV_8UC1);//创建画布

for (int i = 0; i < height; i++)

{

for (int j = 0; j < width; j++)

{

perPixelValue = 255;

horizontalProjectionMat.at(i, j) = perPixelValue;//设置背景为白色

}

}

for (int i = 0; i < height; i++)//水平直方图

{

for (int j = 0; j < projectValArry[i]; j++)

{

perPixelValue = 0;

horizontalProjectionMat.at(i, width - 1 - j) = perPixelValue;//设置直方图为黑色

}

}

vector roiList;//用于储存分割出来的每个字符

int startIndex = 0;//记录进入字符区的索引

int endIndex = 0;//记录进入空白区域的索引

bool inBlock = false;//是否遍历到了字符区内

for (int i = 0; i

{

if (!inBlock && projectValArry[i] != 0)//进入字符区

{

inBlock = true;

startIndex = i;

}

else if (inBlock && projectValArry[i] == 0)//进入空白区

{

endIndex = i;

inBlock = false;

Mat roiImg = srcImg(Range(startIndex, endIndex + 1), Range(0, srcImg.cols));//从原图中截取有图像的区域

roiList.push_back(roiImg);

}

}

delete[] projectValArry;

return roiList;

}

vector verticalProjectionMat(Mat srcImg)//垂直投影

{

Mat binImg;

blur(srcImg, binImg, Size(3, 3));

threshold(binImg, binImg, 0, 255, CV_THRESH_OTSU);

int perPixelValue;//每个像素的值

int width = srcImg.cols;

int height = srcImg.rows;

int* projectValArry = new int[width];//创建用于储存每列白色像素个数的数组

memset(projectValArry, 0, width * 4);//初始化数组

for (int col = 0; col < width; col++)

{

for (int row = 0; row < height;row++)

{

perPixelValue = binImg.at(row, col);

if (perPixelValue == 0)//如果是白底黑字

{

projectValArry[col]++;

}

}

}

Mat verticalProjectionMat(height, width, CV_8UC1);//垂直投影的画布

for (int i = 0; i < height; i++)

{

for (int j = 0; j < width; j++)

{

perPixelValue = 255; //背景设置为白色

verticalProjectionMat.at(i, j) = perPixelValue;

}

}

for (int i = 0; i < width; i++)//垂直投影直方图

{

for (int j = 0; j < projectValArry[i]; j++)

{

perPixelValue = 0; //直方图设置为黑色

verticalProjectionMat.at(height - 1 - j, i) = perPixelValue;

}

}

imshow("垂直投影",verticalProjectionMat);

cvWaitKey(0);

vector roiList;//用于储存分割出来的每个字符

int startIndex = 0;//记录进入字符区的索引

int endIndex = 0;//记录进入空白区域的索引

bool inBlock = false;//是否遍历到了字符区内

for (int i = 0; i < srcImg.cols; i++)//cols=width

{

if (!inBlock && projectValArry[i] != 0)//进入字符区

{

inBlock = true;

startIndex = i;

}

else if (projectValArry[i] == 0 && inBlock)//进入空白区

{

endIndex = i;

inBlock = false;

Mat roiImg = srcImg(Range(0, srcImg.rows), Range(startIndex, endIndex + 1));

roiList.push_back(roiImg);

}

}

delete[] projectValArry;

return roiList;

}

int main(int argc, char* argv[])

{

Mat srcImg = imread("E:\\b.png", 0);//读入原图像

char szName[30] = { 0 };

vector b = verticalProjectionMat(srcImg);//先进行垂直投影

for (int i = 0; i < b.size(); i++)

{

vector a = horizontalProjectionMat(b[i]);//水平投影

sprintf(szName,"E:\\picture\\%d.jpg",i);

for (int j = 0; j < a.size(); j++)

{

imshow(szName,a[j]);

IplImage img = IplImage(a[j]);

cvSaveImage(szName, &img);//保存切分的结果

}

}

/*

vector a = horizontalProjectionMat(srcImg);

char szName[30] = { 0 };

for (int i = 0; i < a.size(); i++)

{

vector b = verticalProjectionMat(a[i]);

for (int j = 0; j

{

sprintf(szName, "E:\\%d.jpg", j);

imshow(szName, b[j]);

}

}

*/

cvWaitKey(0);

getchar();

return 0;

}

以下是程序的结果截图:

(1)原始图像

(2)垂直投影

(3)水平投影

(4)字符切分

由于水平切分的结果只有一个,而垂直切分的结果有多个,所以应该要先进行垂直切分,然后再进行水平切分,这样得到的结果才是切分出字符的大小。若是先进行水平切分,而后进行垂直切分的话,得到的结果就并非要切割出的字符的大小,改代码已经给出,即注释掉的代码,而先进行水平切分,再进行垂直切分的结果如下图所示:

(5)先水平后垂直

可以看到,有的切分出的图像,上下仍然有空白的地方。所以,先水平后垂直的切分方法不适合于本程序的要求。

以上是本人的一点见解,有什么不正确的地方,欢迎指正。

点赞 (4)赏分享 (0)

opencv java水平投影_使用OpenCv中Mat进行水平投影与垂直投影并实现字符切分相关推荐

  1. opencv java 显示图片_【opencv三】利用opencv读取显示图片

    在opencv中读取显示图片的头文件是highgui.hpp. 整体代码如下,如要测试自己的图片,需要将代码段中的图片地址更改为自己图片的绝对路径. #include "opencv2/hi ...

  2. opencv java 车牌定位_用opencv实现在图像找到车牌号并检测出车牌号

    展开全部 整个项目的结构图: 编写DetectFaceDemo.java,代码如下: [java] view plaincopyprint? package com.njupt.zhb.test; i ...

  3. opencv java 人头识别_使用OpenCV人头检测

    [实例简介] 一个应用于公交.汽车.车站商场的人头检测程序,检测出人头进出数量. 输入一幅图片,通过计算指定入口区域的HIST结果,判断是否有人进入.可同时检测2人进入或出去. 一种基于随机Hough ...

  4. 用OpenCv中Mat进行水平投影与垂直投影并实现字符切分

    目前即将开始的一个新项目是进行字符识别,下面就使用水平投影机垂直投影的测试代码贴出,供大家参考. #include<iostream> #include<opencv2\highgu ...

  5. opencv java ubuntu_Ubuntu 16.04配置OpenCV 3.1.0 for Java

    我们都知道,OpenCV是基于C++的开源计算机视觉库,但是从2.4.4版本开始提供了Java绑定,也就是说,我们也可以使用Java来开发基于OpenCV的计算机视觉应用.目前,最新的版本是3.1.0 ...

  6. cv2.error: opencv(4.4.0)_【OpenCV 4开发详解】图像连通域分析

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  7. java coin介绍_代码示例中的Java 7:Project Coin

    java coin介绍 该博客通过代码示例介绍了一些新的Java 7功能,这些项目在Project Coin一词下进行了概述. Project Coin的目标是向JDK 7添加一组小的语言更改.这些更 ...

  8. java方法重载_在Python中该如何实现Java的重写与重载

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:清风python PS:如有需要Python学习资料的小伙伴可以加点击 ...

  9. java 打印abcd_用JAVA编程统计字符串ABCD123!@#$%ab中大写字母、小写字母、数字、其它字符的个数并打印出来...

    /** * 编程统计字符串"ABCD123!@#$%ab"中大写字母.小写字母.数字.其它字符的个数并打 印出来. */ public class Job1Test { publi ...

最新文章

  1. 10.递归是神马?recursion
  2. 用户与服务器的交互:cookies
  3. MATLAB 命令 BOXPLOT
  4. 使用手机游戏的新闻推送
  5. 奇迹世界服务器不响应,sun-奇迹世界 目前常见问题解决方法
  6. mysql 动态hash_python动态渲染库_python 动态渲染 mysql 配置文件的示例
  7. springboot中动态获取bean工具类
  8. Java中的抽象函数与C++中的虚函数
  9. 光标移动事件。 gridview光标移动变色
  10. Algorithms(forth edition),算法(第四版) algs4.jar 与 algs4-data.zip 网盘下载
  11. mysql sin度数正玄值_正弦值角度对照表
  12. 关于学习Godot时遇到的问题(未解决)
  13. 小程序中从后台获取内容纯数字、纯字母超出父盒子宽度时不换行 解决方法
  14. 流式传输 android,如何从android流式传输到ffserver
  15. LG E900 越狱
  16. java随机生成数字和字母_使用java如何生成随机的字母数字字符串?
  17. PPT文件不能编辑怎么回事?
  18. 中国制造构建全球产业链,是关于价值链的创新
  19. 设计师必看的十部电影
  20. python3 练习题100例 (十六)鸡尾酒疗法

热门文章

  1. ListView(2)
  2. 《深度学习》学习的TIP
  3. 漫步数理统计二十——多元随机变量
  4. iris数据集_sklearn日志(二)训练集和测试集划分
  5. 字符编码、常见字符集解析(ASCII、Unicode、UTF-8、GB2312等)
  6. C++的使用Lambda
  7. Opencv--图像颠倒的问题
  8. OpenCV-数字图像处理之直方图均衡化
  9. Android图片上传和下载,android 上传/下载 图片
  10. php 文件上传mime 类型,PHP JAVA C上传文件如何准确判断文件类型-mime知识普及