基于连通域字符分割的流程_基于OpenCV及连通域分析进行文本块分割
上一次通過投影的方式進(jìn)行了文本塊分割,但這種方法有很大的局限性,要求分行清晰、不能有字符跨多行、不能傾斜,而且對噪聲比較敏感。還是拿上一回的圖片,但是我在上面加了一個比較大的字,得出的結(jié)果就有問題了:
可以看到,由于右下角大大的“測”字跨了多行,導(dǎo)致水平投影分行時就出錯了。
本次換一種方法,基于連通性分析來做。簡單講,就是把圖像做一定的膨脹操作,使得同一個字符的不同部分以及相鄰字符相互重疊到一起,變成一個整體,然后再通過分析找到每一個獨(dú)立的塊,排除掉噪聲,剩下的基本就是符合條件的結(jié)果了。
直接上代碼,后面再分析:
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");
//轉(zhuǎn)換到灰度圖
var?gray?=?Cv.CreateImage(src.Size,?BitDepth.U8,?1);
Cv.CvtColor(src,?gray,?ColorConversion.BgrToGray);
//做一下膨脹,x與y方向都做,但系數(shù)不同
var?kernal?=?Cv.CreateStructuringElementEx(5,?2,?1,?1,?ElementShape.Rect);
Cv.Erode(gray,?gray,?kernal,?2);
//二值化
Cv.Threshold(gray,?gray,?0,?255,?ThresholdType.BinaryInv?|?ThresholdType.Otsu);
//檢測連通域,每一個連通域以一系列的點(diǎn)表示,FindContours方法只能得到第一個域
var?storage?=?Cv.CreateMemStorage();
CvSeq?contour?=?null;
Cv.FindContours(gray,?storage,?out?contour,?CvContour.SizeOf,?ContourRetrieval.CComp,?ContourChain.ApproxSimple);
var?color?=?new?CvScalar(0,?0,?255);
//開始遍歷
while?(contour?!=?null)
{
//得到這個連通區(qū)域的外接矩形
var?rect?=?Cv.BoundingRect(contour);
//如果高度不足,或者長寬比太小,認(rèn)為是無效數(shù)據(jù),否則把矩形畫到原圖上
if(rect.Height?>?10?&&?(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();
}
}
}
下面來一步一步分析。讀入的原圖是這樣的:
轉(zhuǎn)換到灰度圖并膨脹處理后,已經(jīng)可以大致看出同一文本塊的多個字符已經(jīng)連到一起了:
二值化后的圖像:
做連通性分析后,原始分析出的結(jié)果是這樣的:
Cv.DrawContours(src,?contour,?color,?color,?1);
對每個連通域取外接矩形,得到的最終結(jié)果是這樣的:
可以看到效果比之前好了很多,比較大的字可以作為獨(dú)立的文本塊被檢測出來了。另外即使是同一行的文本塊,也會有輕微的上下浮動,不再是絕對按行對齊了。
未經(jīng)許可嚴(yán)禁轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的基于连通域字符分割的流程_基于OpenCV及连通域分析进行文本块分割的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea 提示vue插件_Vue + S
- 下一篇: 优秀logo设计解析_必修课 | 抛开固