opencv形态学理解

来源:互联网 发布:java list map 编辑:程序博客网 时间:2024/06/08 08:15

形态学知识

/**************************************************************************/

-代表腐蚀
+代表膨胀
*代表匹配
一下针对的是二值图像,图片指黑底白字
腐蚀
A-B={z|(B)z包含于A}
1.该式指出B对A的腐蚀是一个用z平移的B包含在A中的所有的点z的集合
2.等价于B不与北京共享任何公共元素。
膨胀
A+B={z|(B补)z交A!=空集}
1.该公式是以B关于它的原点的映像,并且以z对映像进行平移为基础的。B对A的膨胀是所有位移z的集合,B补和A至少有一个元素是重叠的。
腐蚀会细化图像,膨胀会粗化图像
开操作    A。B=(A-B)+B    
1.先腐蚀后膨胀,结果是一般会平滑物体的轮廓,断开较窄的狭颈并消除细的突出物
理解:先腐蚀会消除掉比SE小的区域,然后再度膨胀,小的物体会变大,没了的物体就依旧是没了
闭操作    A. B=(A+B)-B
1.先膨胀后腐蚀,通常会弥合较窄的间断和细长的沟壑,消除小的孔洞,填充轮廓线中的断裂
理解:由于膨胀会把原来细小的点,间断点连接起来,再腐蚀会把周围变细,但是内部不变。
击中与击不中变换    A*B=(A-D)交(A补-(W减去D))
理解:不是特别懂。大概就是把B在A中给匹配出来,并且标记为1;在不需要匹配背景的情况下,便可以简化为腐蚀
一些基本的形态学算法
1.边界提取    边界=A减去(A-B)
理解:B腐蚀掉A就会得到A小一圈的部分(即内部),实心图减去内部即得到一个环(边界)
2.孔洞填充    Xk=(Xk-1+B)交A补    迭代至Xk和Xk-1相等为止,然后Xk和原图取交集即可
条件:每个孔洞要预先有填充一个点,B={0,1,0,1,1,1,0,1,0},针对八连通的孔洞
理解:每次对Xk-1进行膨胀时,都会在之前的点的上下左右填充哦你一个点,然后再通过与A补求交集即可得到一个填充区域,最后填充区域与原图求并集就能够填充原图的孔洞。
3.连通分量的提取    Xk=(Xk-1+B)交A    迭代至Xk和Xk-1相等为止
条件:在连通区域要有先填充一个点,B(3,3,CV_8U,Scalar::all(1)),针对八连通的区域
理解:每次对Xk-1进行膨胀时,都会在之前的点周围的八个点填充,然后通过与原图求交集即去掉多余的点,即可得到八连通的区域
4.凸壳    Xk=(Xk-1*B)并A    迭代至Xk和Xk-1相等为止,执行B1,2,3,4,最终将4个并集起来,即可得到凸壳
B={1,X,X
   1,0,X
   1,X,X} B1,2,3,4依次旋转90度
理解:对Xk-1无限次匹配B则会在最右侧形成阶梯的形状,向中间靠拢,直到最右侧只有1或2个高度。其他方向一样理解,并集则是确保包含A,最终4个Xk求并集便是凸壳
5.细化       A细化B=A-(A*B)
当{B}={B1,1,2,3,4,5}时。A细化{B}=(((A细化B1)细化B2)细化B3)……
6.粗化      A粗化B=A并(A*B)
形态学重建
测地膨胀    对集合进行膨胀后与模板求交集,迭代至不再变化为止
测地腐蚀    对集合进行腐蚀后与模板求补集,迭代至不再变化为止
重建开操作提取长字母的理解
先对原图进行n次腐蚀,后进行测地膨胀。n次腐蚀可以提取出原图中长字母的一个点,由于每个字母中间有间隔,每次进行测地膨胀的时候,无关的值在求交集的过程中去掉了,剩下了连续的,与原来模板相关的值。
对填充孔洞,实现字母涂黑的理解
对边界取反色,然后其余部分为黑色,从边界开始以原图的补为模板进行测地膨胀,得到的结果便是原来的白色字体变成了黑色,被黑色字体包围起来的圈也是黑色,其余部分是白色,再对这张图取反,就得到了白色字体里面的白色孔洞被填充了。
边界清除的理解
保留边界的点,然后从这些点开始以原图为模板进行测地膨胀,把原图减去这个结果即可。

灰度级形态学

腐蚀操作,取覆盖区域的最小值
膨胀操作,取覆盖区域的最大值
开操作,在一维的理解下可以认为是一条横线从下往上滑动的最大高度,会截去比较细的部分,变平。
闭操作,从上往下滑动的最低程度,截去低谷部分,变平。
形态学平滑,先进行开操作,再进行闭操作。
形态学梯度,g=(f+b)-(f-b),可以得到和二维微分图像类似的效果。
顶帽变换That=f-(f开b),得到暗背景上的亮物体,可以用来矫正不均匀光照的影响
底帽变换Bhat=f闭b-f,达到的亮背景上的暗物体
灰度级形态学重建
测地膨胀f=min((f+b),g),一样是迭代至不变化为止
测地腐蚀f=max((f-b),g),同上

/**************************************************************************************************************/

介绍一下opencv函数

dilate=膨胀



erode=腐蚀

以上来自于opencv的使用手册

/****************************************************************************************************/

以下是例程(提取长字母和填充字母中的孔洞)

#include<opencv2/opencv.hpp>#include<iostream>using namespace std;using namespace cv;int check_mat(Mat&a,Mat&b)/*判断两幅图像是否相同*/{int ra=a.rows;int ca=a.cols;int rb=b.rows;int cb=b.cols;if(ra!=rb || ca!=cb)return 0;for(int i=0;i<ra;i++){char *pa=a.ptr<char>(i);char *pb=b.ptr<char>(i);for(int j=0;j<ca;j++)if(pa[j]!=pb[j])return 0;}return 1;}void border_f(Mat &src)/*取边框反色,其余置0*/{int r=src.rows;int c=src.cols;for(int i=0;i<r;i++){char*p=src.ptr<char>(i);p[0]=255-p[0];p[c-1]=255-p[c-1];}char*p=src.ptr<char>(0);for(int i=1;i<c-1;i++)p[i]=255-p[i];p=src.ptr<char>(r-1);for(int i=1;i<c-1;i++)p[i]=255-p[i];for(int i=1;i<r-1;i++){char*pt=src.ptr<char>(i);for(int j=1;j<c-1;j++)pt[j]=0;}}int main(int a,char **p){Mat src=imread("eng.png",CV_LOAD_IMAGE_GRAYSCALE);//载入灰度图像threshold(src,src,180,255,1);//二值化,由于我的图像是黑字白底的,所以最后一个参数取1,变成白字黑底imshow("src",src);Mat kern(10,1,CV_8U,Scalar::all(1));//长字符的SEMat kern2(3,3,CV_8U,Scalar::all(1));//3*3的SEMat old_output;erode(src,old_output,kern);//腐蚀dilate(old_output,old_output,kern);//膨胀/*腐蚀再膨胀,便是开操作*/imshow("old_ouput",old_output);Mat re_output;erode(src,re_output,kern);Mat last_output;imshow("re",re_output);//*****************重建开操作******************do{last_output=re_output.clone();dilate(re_output,re_output,kern2);re_output=re_output&src;}while(!check_mat(last_output,re_output));imshow("re_output",re_output);/*提取出了长字符*///******************填充孔洞*******************Mat F=src.clone();/*拷贝一份*/border_f(F);imshow("border_f",F);Mat Ic=Mat::ones(src.size(),CV_8UC1)*255-src;re_output=F;do{last_output=re_output.clone();dilate(re_output,re_output,kern2);re_output=re_output&Ic;}while(!check_mat(last_output,re_output));Mat H=Scalar::all(255)-re_output;imshow("oo",H);/*填充了孔洞*/waitKey();return 0;}

abc

def

a是输入的原图

b是腐蚀后的效果

c是一般的开操作的结果

d是重建开操作后的结果

e是边界取反色,其余置0的效果

f是孔洞填充的效果

原创粉丝点击