數(shù)學(xué)形態(tài)學(xué)是由一組形態(tài)學(xué)的代數(shù)運算子組成的,其常見的運算有膨脹(或擴張)厅贪、腐蝕(或侵蝕)蠢护、開啟、閉合养涮、梯度葵硕、黑帽、頂帽以及擊中擊不中變換等贯吓。我在這兒主要介紹以上8種運算在OpenCV中的使用懈凹。
OpenCV中形態(tài)數(shù)學(xué)的算子實現(xiàn)方法為:morphologyEx()
/**
* 形態(tài)學(xué)濾波函數(shù) morphologyEx()
* 參數(shù)1:輸入的圖片
* 參數(shù)2;輸出的圖片
* 參數(shù)3:形態(tài)學(xué)運算的類型 MORPH_ERODE //腐蝕
* MORPH_DILATE//膨脹
* MORPH_OPEN 開運算
* MORPH_CLOSE 閉運算
* MORPH_GRADIENT 梯度運算
* MORPH_TOPHAT //頂帽
* MORPH_BLACKHAT //黑帽
* MORPH_HITMISS//擊中擊不中變換
* 參數(shù)4:核心悄谐,當(dāng)這個值為NULL時介评,默認(rèn)為3*3的核
* 參數(shù)5:錨點
* 參數(shù)6:迭代次數(shù)
* 參數(shù)7:邊界模式
* 參數(shù)8:邊界值為常數(shù)時,會有默認(rèn)值
*/
CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst,int op, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );
膨脹
膨脹:參照核爬舰,求局部最大值们陆,因此亮度高的地方會擴大。具體介紹參考:這里寫鏈接內(nèi)容
Mat img(h,w,CV_8UC4,pixels);
//核心
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//膨脹運算
morphologyEx(img,img,MORPH_DILATE,coreMat);
腐蝕
腐蝕:參照核情屹, 求局部最小值坪仇,因此暗的地方會越來越大。具體介紹參考:這里寫鏈接內(nèi)容
Mat img(h,w,CV_8UC4,pixels);
//核心
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//腐蝕運算
morphologyEx(img,img,MORPH_ERODE,coreMat);
開運算
開運算:先腐蝕后膨脹垃你,消除小物體椅文,在纖細(xì)點分離物體,平滑較大物體的邊界惜颇,操作的同時原圖大小改變不明顯皆刺。
Mat img(h,w,CV_8UC4,pixels);
//核心
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//開運算
morphologyEx(img,img,MORPH_OPEN,coreMat);
閉運算
閉運算:先膨脹后腐蝕,消除小型黑洞凌摄,是圖像更新鮮活明亮羡蛾。
Mat img(h,w,CV_8UC4,pixels);
//核心
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//閉運算
morphologyEx(img,img,MORPH_CLOSE,coreMat);
梯度
形態(tài)學(xué)梯度:膨脹圖與腐蝕圖之差(dilate- erode), 可以保留物體的邊緣輪廓锨亏。
Mat img(h,w,CV_8UC4,pixels);
vector<Mat> outchannl;
//顏色分離
split(img,outchannl);
Mat out3img;
//顏色形態(tài)轉(zhuǎn)換
cvtColor(img,out3img,COLOR_BGRA2BGR);
//核
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//形態(tài)學(xué)梯度運算
morphologyEx(out3img,out3img,MORPH_GRADIENT,coreMat);
uchar * ptr = img.ptr(0);
uchar *out = out3img.ptr(0);
//只取BGR
for (int i = 0; i < h * w; ++i) {
ptr[4*i+0] = out[3*i+0];
ptr[4*i+1] = out[3*i+1];
ptr[4*i+2] = out[3*i+2];
}
頂帽
頂帽:原圖和開運算之差痴怨,做背景提燃逡蟆(有大背景或者微小物體有規(guī)律的時候)。
Mat img(h,w,CV_8UC4,pixels);
vector<Mat> outchannl;
//顏色分離
split(img,outchannl);
Mat out3img;
//顏色形態(tài)轉(zhuǎn)換
cvtColor(img,out3img,COLOR_BGRA2BGR);
//核
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//頂帽運算
morphologyEx(out3img,out3img,MORPH_TOPHAT,coreMat);
uchar * ptr = img.ptr(0);
uchar *out = out3img.ptr(0);
//只取BGR
for (int i = 0; i < h * w; ++i) {
ptr[4*i+0] = out[3*i+0];
ptr[4*i+1] = out[3*i+1];
ptr[4*i+2] = out[3*i+2];
}
黑帽
黑帽:閉運算和原圖之差腿箩,可以得到一個完美的輪廓圖豪直。
Mat img(h,w,CV_8UC4,pixels);
vector<Mat> outchannl;
//顏色分離
split(img,outchannl);
Mat out3img;
//顏色形態(tài)轉(zhuǎn)換
cvtColor(img,out3img,COLOR_BGRA2BGR);
//核
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//黑帽運算
morphologyEx(out3img,out3img,MORPH_BLACKHAT,coreMat);
uchar * ptr = img.ptr(0);
uchar *out = out3img.ptr(0);
//只取BGR
for (int i = 0; i < h * w; ++i) {
ptr[4*i+0] = out[3*i+0];
ptr[4*i+1] = out[3*i+1];
ptr[4*i+2] = out[3*i+2];
}
擊中擊不中變換
擊中-擊不中運算常用于二值圖像,它用于基于結(jié)構(gòu)元素的配置珠移,從圖像中尋找具有某種像素排列特征的目標(biāo)弓乙,如單個像素、顆粒中交叉或縱向的特征钧惧、直角邊緣或其他用戶自定義的特征等暇韧。計算時,只有當(dāng)結(jié)構(gòu)元素與其覆蓋的圖像區(qū)域完全相同時浓瞪,中心像素的值才會被置為1懈玻,否則為0。相對于原圖直接減去腐蝕的圖像乾颁,擊中擊不中變換保留了更多的細(xì)節(jié)涂乌,邊緣也更加明顯突出赔硫。
Mat img(h,w,CV_8UC4,pixels);
Mat out;
//轉(zhuǎn)換為單通道圖片
cvtColor(img,out,COLOR_BGR2GRAY);
//核
Mat coreMat = getStructuringElement(MORPH_RECT,Size(10,10));
//擊中擊不中變換運算 src.type() == CV_8UC1
morphologyEx(out,out,MORPH_HITMISS,coreMat);
uchar *ptr = img.ptr(0);
uchar *outPtr = out.ptr(0);
int size = w*h;
for (int i = 0; i < size; ++i) {
ptr[4*i+0] = outPtr[I];
ptr[4*i+1] = outPtr[I];
ptr[4*i+2] = outPtr[I];
}
本文章著作版權(quán)所屬:微笑面對,請關(guān)注我的CSDN博客:博客地址