http://blog.youkuaiyun.com/byxdaz/article/details/5775717
OpenCV形態學操作
一、圖像腐蝕 膨脹 細化的基本原理
1.圖像細化的基本原理
⑸ 開閉操作 閉操作是先膨脹、後腐蝕處理。
(6) 細化 |
具體詳細的圖像形態學資料參考:http://wenku.baidu.com/view/1923d18fcc22bcd126ff0ccc.html
二、OpenCv形態學操作相關函數
1、MorphologyEx 高級形態學變換
void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp,
IplConvKernel* element, int operation, int iterations=1 );
src
輸入圖像.
dst
輸出圖像.
temp
臨時圖像,某些情況下需要
element
結構元素
operation
形態操作的類型:
CV_MOP_OPEN - 開運算
CV_MOP_CLOSE - 閉運算
CV_MOP_GRADIENT - 形態梯度
CV_MOP_TOPHAT - "頂帽"
CV_MOP_BLACKHAT - "黑帽"
iterations
膨脹和腐蝕次數.
函數 cvMorphologyEx 在膨脹和腐蝕基本操作的基礎上,完成一些高級的形態變換:
開運算
dst=open(src,element)=dilate(erode(src,element),element)
閉運算
dst=close(src,element)=erode(dilate(src,element),element)
形態梯度
dst=morph_grad(src,element)=dilate(src,element)-erode(src,element)
"頂帽"
dst=tophat(src,element)=src-open(src,element)
"黑帽"
dst=blackhat(src,element)=close(src,element)-src
臨時圖像 temp 在形態梯度以及對「頂帽」和「黑帽」操作時的 in-place 模式下需要。
2、Dilate 使用任意結構元素膨脹圖像
void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );
src
輸入圖像.
dst
輸出圖像.
element
用於膨脹的結構元素。若為 NULL, 則使用 3×3 長方形的結構元素
iterations
膨脹的次數
函數 cvDilate 對輸入圖像使用指定的結構元進行膨脹,該結構決定每個具有最小值象素點的鄰域形狀:
dst=dilate(src,element): dst(x,y)=max((x',y') in element))src(x+x',y+y')
函數支持(in-place)模式。膨脹可以重復進行 (iterations) 次. 對彩色圖像,每個彩色通道單獨處理。
3、Erode 使用任意結構元素腐蝕圖像
void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );
src
輸入圖像.
dst
輸出圖像.
element
用於腐蝕的結構元素。若為 NULL, 則使用 3×3 長方形的結構元素
iterations
腐蝕的次數
函數 cvErode 對輸入圖像使用指定的結構元素進行腐蝕,該結構元素決定每個具有最小值象素點的鄰域形狀:
dst=erode(src,element): dst(x,y)=min((x',y') in element))src(x+x',y+y')
函數可能是本地操作,不需另外開辟存儲空間的意思。腐蝕可以重復進行 (iterations) 次. 對彩色圖像,每個彩色通道單獨處理。
注:CreateStructuringElementEx 創建結構元素;ReleaseStructuringElement 刪除結構元素。
三、OpenCv形態學實例代碼:
1、腐蝕、膨脹、開運算、閉運算
內容參考:http://blog.youkuaiyun.com/gnuhpc/archive/2009/06/21/4286177.aspx
/*******************************
數學形態運算,最常見的基本運算有七種,
分別為:腐蝕、膨脹、開運算、閉運算、擊中、細化和粗化,
它們是全部形態學的基礎。
********************************/
#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>
IplImage *src=0;
IplImage *dst=0;
IplConvKernel *element=0;//聲明一個結構元素
int element_shape=CV_SHAPE_RECT;//長方形形狀的元素
int max_iters=10;
int open_close_pos=0;
int erode_dilate_pos=0;
void OpenClose(int pos)
{
int n=open_close_pos-max_iters;
int an=n>0?n:-n;
element = cvCreateStructuringElementEx(an*2+1, an*2+1,an,an,element_shape,0);//創建結構元素
if (n<0)
{
cvErode(src,dst,element,1);//腐蝕圖像
cvDilate(dst,dst,element,1);//膨脹圖像
}
else
{
cvDilate(dst,dst,element,1);//膨脹圖像
cvErode(src,dst,element,1);//腐蝕圖像
}
cvReleaseStructuringElement(&element);
cvShowImage("Open/Close",dst);
}
void ErodeDilate(int pos)
{
int n=erode_dilate_pos-max_iters;
int an=n>0?n:-n;
element = cvCreateStructuringElementEx(an*2+1,an*2+1,an,an,element_shape,0);
if (n<0)
{
cvErode(src,dst,element,1);
}
else
{
cvDilate(src,dst,element,1);
}
cvReleaseStructuringElement(&element);
cvShowImage("Erode/Dilate",dst);
}
int main(int argc,char **argv)
{
char *filename =argc ==2?argv[1]:(char *)"lena.jpg";
if( (src = cvLoadImage(filename,1)) == 0 )
return -1;
dst=cvCloneImage(src);
cvNamedWindow("Open/Close",1);
cvNamedWindow("Erode/Dilate",1);
open_close_pos = erode_dilate_pos = max_iters;
cvCreateTrackbar("iterations","Open/Close",&open_close_pos,max_iters*2+1,OpenClose);
cvCreateTrackbar("iterations","Erode/Dilate",&erode_dilate_pos,max_iters*2+1,ErodeDilate);
for (;;)
{
int c;
OpenClose(open_close_pos);
ErodeDilate(erode_dilate_pos);
c= cvWaitKey(0);
if (c==27)
{
break;
}
switch(c) {
case 'e':
element_shape=CV_SHAPE_ELLIPSE;
break;
case 'r':
element_shape=CV_SHAPE_RECT;
break;
case '/r':
element_shape=(element_shape+1)%3;
break;
default:
break;
}
}
cvReleaseImage(&src);
cvReleaseImage(&dst);
cvDestroyWindow("Open/Close");
cvDestroyWindow("Erode/Dilate");
return 0;
}
/*****************************
腐蝕和膨脹,看上去好像是一對互逆的操作,實際上,這兩種操作不具有互逆的關系。
開運算和閉運算正是依據腐蝕和膨脹的不可逆性,演變而來的。
先腐蝕後膨脹的過程就稱為開運算。
閉運算是通過對腐蝕和膨脹的另一種不同次序的執行而得到的,
閉運算是先膨脹後腐蝕的過程,其功能是用來填充物體內細小空洞、連接鄰近物體、平滑其邊界,
同時不明顯改變不明顯改變其面積。
******************************/
2、opencv實現二值圖像細化
內容參考:http://blog.youkuaiyun.com/byxdaz/archive/2010/06/02/5642669.aspx