上一次通过投影的方式进行了文本块分割,(见 https://www.cnblogs.com/BoyTNT/p/11812323.html )但这种方法有很大的局限性,要求分行清晰、不能有字符跨多行、不能倾斜,而且对噪声比较敏感。还是拿上一回的图片,但是我在上面加了一个比较大的字,得出的结果就有问题了:

可以看到,由于右下角大大的“测”字跨了多行,导致水平投影分行时就出错了。

本次换一种方法,基于连通性分析来做。简单讲,就是把图像做一定的膨胀操作,使得同一个字符的不同部分以及相邻字符相互重叠到一起,变成一个整体,然后再通过分析找到每一个独立的块,排除掉噪声,剩下的基本就是符合条件的结果了。

直接上代码,后面再分析:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text; using OpenCvSharp;
using OpenCvSharp.Extensions;
using OpenCvSharp.Utilities; namespace OpenCvTest
{
class Program
{
static void Main(string[] args)
{
//读入源文件
var src = IplImage.FromFile("source.jpg"); //转换到灰度图
var gray = Cv.CreateImage(src.Size, BitDepth.U8, );
Cv.CvtColor(src, gray, ColorConversion.BgrToGray); //做一下膨胀,x与y方向都做,但系数不同
//使用了Erode方法,腐蚀操作,针对白色区域,所以等效于对文字进行了膨胀
var kernal = Cv.CreateStructuringElementEx(, , , , ElementShape.Rect);
Cv.Erode(gray, gray, kernal, ); //二值化
Cv.Threshold(gray, gray, , , ThresholdType.BinaryInv | ThresholdType.Otsu); //检测连通域,每一个连通域以一系列的点表示,FindContours方法只能得到第一个域
var storage = Cv.CreateMemStorage();
CvSeq<CvPoint> contour = null;
Cv.FindContours(gray, storage, out contour, CvContour.SizeOf, ContourRetrieval.CComp, ContourChain.ApproxSimple);
var color = new CvScalar(, , ); //开始遍历
while (contour != null)
{
//得到这个连通区域的外接矩形
var rect = Cv.BoundingRect(contour); //如果高度不足,或者长宽比太小,认为是无效数据,否则把矩形画到原图上
if(rect.Height > && (rect.Width * 1.0 / rect.Height) > 0.2)
Cv.DrawRect(src, rect, color); //取下一个连通域
contour = contour.HNext;
}
Cv.ReleaseMemStorage(storage); //显示
Cv.ShowImage("Result", src);
Cv.WaitKey();
Cv.DestroyAllWindows();
}
}
}

下面来一步一步分析。读入的原图是这样的:

转换到灰度图并膨胀处理后,已经可以大致看出同一文本块的多个字符已经连到一起了:

二值化后的图像:

做连通性分析后,原始分析出的结果是这样的:

Cv.DrawContours(src, contour, color, color, );

对每个连通域取外接矩形,得到的最终结果是这样的:

可以看到效果比之前好了很多,比较大的字可以作为独立的文本块被检测出来了。另外即使是同一行的文本块,也会有轻微的上下浮动,不再是绝对按行对齐了。

未经许可严禁转载。

基于OpenCV.Net连通域分析进行文本块分割的更多相关文章

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

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

  2. 基于Opencv自带BP网络的车标简易识别

    代码地址如下:http://www.demodashi.com/demo/12966.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 1.准备工作 1.1 训练集和测 ...

  3. 基于OpenCV制作道路车辆计数应用程序

    基于OpenCV制作道路车辆计数应用程序 发展前景 随着科学技术的进步和工业的发展,城市中交通量激增,原始的交通方式已不能满足要求:同时,由于工业发展为城市交通提供的各种交通工具越来越多,从而加速了城 ...

  4. 每日一练之自适应中值滤波器(基于OpenCV实现)

    本文主要介绍了自适应的中值滤波器,并基于OpenCV实现了该滤波器,并且将自适应的中值滤波器和常规的中值滤波器对不同概率的椒盐噪声的过滤效果进行了对比.最后,对中值滤波器的优缺点了进行了总结. 空间滤 ...

  5. Csharp调用基于Opencv编写的类库文件

    现在将Csharp调用基于Opencv编写的类库文件(Dll)的方法定下来,我取名叫做GreenOpenCsharpWarper,简称GOCW. 一.CLR编写的DLL部分 1.按照正常方法引入Ope ...

  6. 图像处理基础(2):自适应中值滤波器(基于OpenCV实现)

    本文主要介绍了自适应的中值滤波器,并基于OpenCV实现了该滤波器,并且将自适应的中值滤波器和常规的中值滤波器对不同概率的椒盐噪声的过滤效果进行了对比.最后,对中值滤波器的优缺点了进行了总结. 空间滤 ...

  7. 为基于OpenCV的图像处理程序编写界面—关于QT\MFC\CSharp的选择以及GOCW的介绍

            基于OpenCV编写图像处理项目,除了算法以外,比较重要一个问题就是界面设计问题.对于c++语系的程序员来说,一般来说有QT/MFC两种考虑.QT的确功能强大,特别是QML编写andr ...

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

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

  9. 基于CommonsCollections4的Gadget分析

    基于CommonsCollections4的Gadget分析 Author:Welkin 0x1 背景及概要 随着Java应用的推广和普及,Java安全问题越来越被人们重视,纵观近些年来的Java安全 ...

随机推荐

  1. JAVA----HelloWorld

    1.步骤 将java代码编写到扩展名为.java的文件中(扩展名的查看) 新建文本文档,重命名为Test.java. 以记事本方式打开. 写入代码. public class Test{       ...

  2. 配置flutter For IOS

    https://www.cnblogs.com/lovestarfish/p/10628205.html 第一步,下载flutter最新版,解压到自己的目录里: 提供网址:https://flutte ...

  3. C语言、指针(一)

    指针(一) “带*类型” 的特征探测:宽度 “带*类型” 的特征探测:声明 “带*类型” 的特征探测:赋值 “带*类型” 的特征探测:++ -- “带*类型” 的特征探测:加上/减去 一个整数 “带* ...

  4. 【微信小程序】安装DingoApi开发小程序api

    1.安装 composer require dingo/api 2.发布配置: php artisan vendor:publish 选择DingoApi发布. 3.向.env文件添加配置 (1)项目 ...

  5. 8.python3实用编程技巧进阶(三)

    3.1.如何实现可迭代对象和迭代器对象 #3.1 如何实现可迭代对象和迭代器对象 import requests from collections.abc import Iterable,Iterat ...

  6. Mysql双主加Keepalived+读写分离

    一.MySQL于keepalived简介** 前言: 在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要 ...

  7. 在MVC视图中将数字转换为string类型后保留两位小数

    <td>@item.recharge_reward_rate.ToString("F2")%</td> @*保留小数两位*@ <td>@item ...

  8. fastdfs-nginx-module安装和配置

    fastdfs-nginx-module安装和配置 为什么要在fastdfs的storage端,安装fastdfs-nginx-module? 答案:https://www.cnblogs.com/l ...

  9. Java学习笔记(1)--- 简介

    简介: 注:和之前的C不一样,本人没有学过java,所以内容上可能会相对详细一些. 主要特性: 1.这跟c++一样是面对对象语言: Java语言提供类.接口和继承等面向对象的特性,为了简单起见,只支持 ...

  10. Windows文件夹共享和Unity的PersisterdataPath

    在共享机上存放unity开发的pc版本游戏,在其它机器双击就可以运行,但会遇到问题,比如: 游戏是需要下载资源的,默认情况下unity下载的资源是存放在persisterdataPath目录的,对于w ...