OpenCV 实现图片的水平投影与垂直投影,并进行行分割
对于印刷体图片来说,进行水平投影和垂直投影可以很快的进行分割,本文就在OpenCV中如何进行水平投影和垂直投影通过代码进行说明。
水平投影:二维图像在y轴上的投影
垂直投影:二维图像在x轴上的投影
由于投影的图像需要进行二值化,本文采用积分二值化的方式,对图片进行处理。
具体代码如下:
//积分二值化
void thresholdIntegral (Mat inputMat, Mat& outputMat)
{
int nRows = inputMat.rows;
int nCols = inputMat.cols;
// create the integral image
Mat sumMat;
integral (inputMat, sumMat);
;
double T = 0.15;
// perform thresholding
;
int x1, y1, x2, y2, count, sum;
int* p_y1, *p_y2;
uchar* p_inputMat, *p_outputMat;
; i < nRows; ++i)
{
y1 = i - s2;
y2 = i + s2;
)
{
y1 = ;
}
if (y2 >= nRows)
{
y2 = nRows - ;
}
p_y1 = sumMat.ptr<int> (y1);
p_y2 = sumMat.ptr<int> (y2);
p_inputMat = inputMat.ptr<uchar> (i);
p_outputMat = outputMat.ptr<uchar> (i);
; j < nCols; ++j)
{
// set the SxS region
x1 = j - s2;
x2 = j + s2;
)
{
x1 = ;
}
if (x2 >= nCols)
{
x2 = nCols - ;
}
count = (x2 - x1)* (y2 - y1);
// I(x,y)=s(x2,y2)-s(x1,y2)-s(x2,y1)+s(x1,x1)
sum = p_y2[x2] - p_y1[x2] - p_y2[x1] + p_y1[x1];
if ((int) (p_inputMat[j] * count) < (int) (sum* (1.0 - T)))
{
p_outputMat[j] = ;
}
else
{
p_outputMat[j] = ;
}
}
}
}
//垂直方向投影
void picshadowx (Mat binary)
{
Mat paintx (binary.size(), CV_8UC1, Scalar ()); //创建一个全白图片,用作显示
int* blackcout = new int[binary.cols];
memset (blackcout, , binary.cols * );
; i < binary.rows; i++)
{
; j < binary.cols; j++)
{
)
{
blackcout[j]++; //垂直投影按列在x轴进行投影
}
}
}
; i < binary.cols; i++)
{
; j < blackcout[i]; j++)
{
paintx.at<uchar> (binary.rows--j, i) = ; //翻转到下面,便于观看
}
}
delete blackcout;
imshow ("paintx", paintx);
}
//水平方向投影并行分割
void picshadowy (Mat binary)
{
//是否为白色或者黑色根据二值图像的处理得来
Mat painty (binary.size(), CV_8UC1, Scalar ()); //初始化为全白
//水平投影
int* pointcount = new int[binary.rows]; //在二值图片中记录行中特征点的个数
memset (pointcount, , binary.rows * );//注意这里需要进行初始化
; i < binary.rows; i++)
{
; j < binary.cols; j++)
{
)
{
pointcount[i]++; //记录每行中黑色点的个数 //水平投影按行在y轴上的投影
}
}
}
; i < binary.rows; i++)
{
; j < pointcount[i]; j++) //根据每行中黑色点的个数,进行循环
{
painty.at<uchar> (i, j) = ;
}
}
imshow ("painty", painty);
vector<Mat> result;
;
;
bool inblock = false; //是否遍历到字符位置
; i < painty.rows; i++)
{
) //进入有字符区域
{
inblock = true;
startindex = i;
cout << "startindex:" << startindex << endl;
}
) //进入空白区
{
endindex = i;
inblock = false;
Mat roi = binary.rowRange (startindex, endindex+); //从而记录从开始到结束行的位置,即可进行行切分
result.push_back (roi);
}
}
; i < result.size(); i++)
{
Mat tmp = result[i];
imshow ("test"+to_string (i), tmp);
}
delete pointcount;
}
int main (int argc, char* argv[])
{
Mat src = cv::imread ("test.jpg");
if (src.empty())
{
cerr << "Problem loading image!!!" << endl;
;
}
imshow("in",src);
Mat gray;
)
{
cv::cvtColor (src, gray, CV_BGR2GRAY);
}
else
{
gray = src;
}
Mat bw2 = Mat::zeros (gray.size(), CV_8UC1);
thresholdIntegral (gray, bw2);
cv::imshow ("binary integral", bw2);
//picshadowx (bw2);
picshadowy (bw2);
waitKey ();
;
}
输入图片:

二值图片:

水平投影:

垂直投影:

行切割:


OpenCV 实现图片的水平投影与垂直投影,并进行行分割的更多相关文章
- python 对图片做垂直投影
Python 对图片做垂直投影 本文利用opencv对图片进行垂直投影,做出垂直投影图,大体思路:打开图片,灰度化,二值化,按列进行统计,新建一个大小和原图一样的图片,按列进行填充: cv2.cv.G ...
- Python + opencv 实现图片文字的分割
实现步骤: 1.通过水平投影对图形进行水平分割,获取每一行的图像: 2.通过垂直投影对分割的每一行图像进行垂直分割,最终确定每一个字符的坐标位置,分割出每一个字符: 先简单介绍一下投影法:分别在水平和 ...
- 用 Python 和 OpenCV 检测图片上的条形码
用 Python 和 OpenCV 检测图片上的的条形码 这篇博文的目的是应用计算机视觉和图像处理技术,展示一个条形码检测的基本实现.我所实现的算法本质上基于StackOverflow 上的这个问 ...
- CSS实现文字和图片的水平垂直居中
关于文字和图片的水平垂直居中,在前端界绝对算是一个老生常谈的问题了,尤其是垂直居中,什么千奇百怪的解法都能想的出来.下面我就总结一些比较常用的方法: 一.文本的水平垂直居中: 1.水平居中: 是不是很 ...
- mysql的水平拆分和垂直拆分
转:http://www.cnblogs.com/sns007/p/5790838.html 1,水平分割: 例:QQ的登录表.假设QQ的用户有100亿,如果只有一张表,每个用户登录的时候数据库都要从 ...
- MYSQL水平拆分与垂直拆分
目前很多互联网系统都存在单表数据量过大的问题,这就降低了查询速度,影响了客户体验.为了提高查询速度,我们可以优化sql语句,优化表结构和索引,不过对那些百万级千万级的数据库表,即便是优化过后,查询速度 ...
- * CSS 视觉格式化(基本框、包含块、盒模型、水平格式化、垂直格式化、行布局、em框、内容区、行间距、行内框、行框)
前言 CSS视觉格式化这个词可能比较陌生,但说起盒模型可能就恍然大悟了.实际上,盒模型只是CSS视觉格式化的一部分.视觉格式化分为块级和行内两种处理方式.理解视觉格式化,可以确定得到的效果是应该显示的 ...
- mysql的水平拆分和垂直拆分 (转)
http://www.cnblogs.com/sns007/p/5790838.html 1,水平分割: 例:QQ的登录表.假设QQ的用户有100亿,如果只有一张表,每个用户登录的时候数据库都要从这1 ...
- mysql数据库的水平拆分与垂直拆分
近端时间在面试,发现很多面试官或者面试都把数据的水平拆分合垂直拆分给搞混了,今天特意写了一篇博客来说说水平拆分和垂直拆分希望对程序猿们有所帮助. 数据库水平与垂直拆分: 垂直(纵向)拆分:是指按功能模 ...
随机推荐
- Long Long Message(后缀数组)
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 30427 Accepted: 12 ...
- 0_Simple__cppOverload
使用cuda内质结构 cudaFuncAttributes 来观察核函数的共享内存.寄存器数量. ▶ 源代码: /*cppOverload_kernel.cuh*/ __global__ void s ...
- 原生promise
你应该会用事件加回调的办法来处理这类情况: var img1 = document.querySelector('.img-1'); img1.addEventListener('load', f ...
- 关于viewports 设备像素比 密度
首先追溯到像素,第一个麻烦事像素的总量问题,同样的大小的屏幕像素可以差很远,像素大小更小的导致内容也变小 在小屏幕上如果展示巨大的桌面网页,诺基亚的做法是首先载入完整的桌面网页,然后缩放至设备屏幕 ...
- python利用django实现简单的登录和注册,并利用session实现了链接数据库
利用session实现与数据库链接,登录模块(在views.py) def login(request): # return HttpResponseRedirect('/') # 判断是否post方 ...
- Linux 新建文件/文件夹,删除文件文件夹,查找文件 打开文件
1.新建文件夹:mkdir xx 2.新建文件: touch 1.py 3.删除文件/文件夹: rm -r xx rm 1.py 4.打开文件:cat 1.py 只显示前几行 :head -2 1. ...
- Python丨Python 性能分析大全
虽然运行速度慢是 Python 与生俱来的特点,大多数时候我们用 Python 就意味着放弃对性能的追求.但是,就算是用纯 Python 完成同一个任务,老手写出来的代码可能会比菜鸟写的代码块几倍,甚 ...
- docker下编译mangoszero WOW60级服务端(二)
开始搭建基于docker的mangoszero WOW服务端,我自己的操作系统是mac os,其他平台操作可以等价替换 1.准备工作 (1) 安装docker,参考docker官方文档,https:/ ...
- 六:在线工具网站,让你PC上要装的软件少一半!
记住这几个在线工具网站,让你PC上要装的软件少一半! 一.uzer.me——丰富的云端应用聚合 这个云平台将我们常用的Office系列软件.Adobe家族的系列软件……乃至CAD制图都整合在了云端,随 ...
- CentOS7.x系统根目录分区扩容
说明:系统版本为 Linux version 3.10.0-327.el7.x86_64 step1. 查看现有磁盘信息,可以看出根分区有45G [root@DEV-CMDB-DB02 ~]# df ...