基本形态学算法
为什么要做基本形态学算法的研究和实现?是因为形态学是一个非常有力,应用 广泛的工具,但同时也是研究不是很清楚的工具。往往一个恰到好处的变换,就能够省下许多的劳动。对此的分类和研究就显得非常有必要,而相关代码的积累,也很有价值。
零、基本概念:
膨胀:白->黑; dilate
腐蚀:黑->白; erode
开 : 腐蚀->膨胀 平滑物体轮廓,断开较窄的地方,清除细突;
闭 :膨胀->腐蚀 弥合较窄的间断,填补细长的沟壑;
顶帽 :src-(开运算(src))
底帽 :闭运算(src)-src
一、边界提取
先腐蚀,然后相减。
作为生成算法可能价值不是很大,但是在生成镂空字符的时候,价值就会比较大。
变成
以及
//-------------------生成验证码--------------//
void
creatCode()
{
Mat edge;
Mat code
=
imread(
"abcd123.bmp"
,
0
);
threshold(code,code,
0
,
255
,THRESH_OTSU);
threshold(code,code,
0
,
255
,THRESH_BINARY_INV);
dilate(code,code,Mat(
1
,
5
,CV_8U));
erode(code,edge,Mat());
edge
=
code
-
edge;
imshow(
"验证码生成"
,code);
}
//-------------------边界提取----------------//
void
getEdge(Mat src)
{
Mat edge ;
erode(src,edge,Mat());
edge
=
src
-
edge;
imshow(
"边界提取"
,edge);
}
二、孔洞填充(注意,floodfill是没有教程的)
一个孔洞可以被定义为由前景像素相连接的边界所包围的一个背景区域。关键是标注出区域中的点来。
原文的翻译实在无法理解。我这里做出自己收集到的实现。
opencv中提供了floodfill的例子,应该说功能强大
对于本例,问题在于如何自动化这个过程?
我实现了一个效果,主要是通过反过来找中间的黑点,然后相加。这里属于反过来使用floodfill,效果还是不错的.
NICE!体现形态学的强大能力。如果你用轮廓来找的话,会很麻烦,而且不稳定。但是用形态学,确非常稳定,只有在很特殊的情况下,才可能出现失败的青年高考。
三、联通分量提取
从二值图像中提取联通分量是许多自动图形啊分析应用的核心。除了在对应A中每个连通分量中的一个点的已指的每一个位置我们置为1,其他为0
对于8连通,目前采用的算法是find contours。虽然有一些文档中也提出了一些算法,但是根据我目前的知识结构,还是直接contour的方法最好。
四、【关于细化和骨廓,届时看不懂】
五、顶帽变换和底帽变换
顶帽变换的一个作用是去除光照不均匀
用于连铸的效果非常明显,我相信这样可以把代码质量进一步提高
黑帽
去除背景还是要这样来做
从这点可以看出,它的确是效果要更好一点的。
小结:
形态学变换应该说是很强的,因为它更接近于原始的情况,是不同于轮廓分析的基础工具。在我之前的过程中确实缺乏这方面的使用,这方面的书还要多读多用。
P.S.
在OPENCV中,提供了一揽子的解决方法
int main()
{
Mat src = imread("./image/chars_identify.jpg",0);
Mat srcClone = src.clone();
Mat element = getStructuringElement(MORPH_ELLIPSE,Size(7,3));
morphologyEx(src,srcClone,CV_MOP_TOPHAT,element);
imshow("src",src);
imshow("srcClone",srcClone);
waitKey();
}
分为两个部分,首先生成一个element,然后根据参数的不同,进行形态学变换
/* Morphological operations */
enum
{
CV_MOP_ERODE =0,
CV_MOP_DILATE =1,
CV_MOP_OPEN =2,
CV_MOP_CLOSE =3,
CV_MOP_GRADIENT =4,
CV_MOP_TOPHAT =5,
CV_MOP_BLACKHAT =6
};