opencv--形態學操作
開操作
- 功能
消除小物體;
在纖細處分離物體;
平滑較大的邊界並不明顯改變其面積; - 數學公式
閉操作
- 功能
消除小型黑洞(黑斑)。 - 數學公式
形態學梯度
- 功能
對二值影象進行這一操作可以將團塊(blob)的邊緣突出來。我們可以用形態學梯度來保留物體的邊緣輪廓。 - 數學公式
頂帽
-
功能
因為開運算帶來的結果是放大了裂縫或者區域性低亮度的區域,因此,從原圖中減去開運算後的圖,得到的效果圖突出了比原型輪廓周圍的區域更明亮的區域。且這一操作和選擇的核的大小有關。頂帽運算往往用來分離比鄰近點亮一些的斑塊。當一幅影象具有大幅的背景的時候,而微小物品比較有規律的時候,可以用頂帽運算進行背景提取。
-
數學公式
為原影象與上文剛介紹的“開運算”的結果圖之差,表示式如下:
黑帽
-
功能
黑帽(Black Hat)運算為”閉運算“的結果圖與原影象之差。黑帽運算後的效果圖突出了比原圖輪廓周圍的區域更暗的區域,且這一操作和選擇的核的大小相關。
所以,黑帽運算用來分離比鄰近點暗一些的斑塊。 -
數學表示式:
相關API
- 宣告
void morphologyEx( InputArray src, // OutputArray dst,// int op,//形態學運算的型別 InputArraykernel, Pointanchor=
- 引數
-
第一個引數,InputArray型別的src,輸入影象,即源影象,填Mat類的物件即可。影象位深應該為以下五種之一:CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F。
-
第二個引數,OutputArray型別的dst,即目標影象,函式的輸出引數,需要和源圖片有一樣的尺寸和型別。
-
int op:表示形態學運算的型別
MORPH_OPEN – 開運算(Opening operation)
MORPH_CLOSE – 閉運算(Closing operation)
MORPH_GRADIENT -形態學梯度(Morphological gradient)
MORPH_TOPHAT - “頂帽”(“Top hat”)
MORPH_BLACKHAT - “黑帽”(“Black hat“) -
第四個引數,InputArray型別的kernel,形態學運算的核心。若為NULL時,表示的是使用參考點位於中心3x3的核。我們一般使用函式 getStructuringElement配合這個引數的使用。getStructuringElement函式會返回指定形狀和尺寸的結構元素(核心矩陣)。
Mat src,dst1, dst2,dst3,dst4,dst5,dst6,dst7;
int step_size = 3;
int max_size = 21;
void my_dilate(int ,void*) {
int s = step_size * 2 + 1;
Mat structingElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));
dilate(src, dst1, structingElement);
imshow("dilate", dst1);
return;
}
void my_erode(int, void*) {
int s = step_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s));
erode(src, dst2, kernel);
imshow("erode", dst2);
return;
}
void my_open(int, void*) {
int s = step_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s));
morphologyEx(src, dst3, MORPH_OPEN, kernel);
imshow("open", dst3);
}
void my_close(int, void*) {
int s = step_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s));
morphologyEx(src, dst4, MORPH_CLOSE, kernel);
imshow("close", dst4);
}
void my_gradient(int, void*) {
int s = step_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s));
morphologyEx(src, dst5, MORPH_GRADIENT, kernel);
imshow("gradient", dst5);
}
void my_tophat(int, void*) {
int s = step_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s));
morphologyEx(src, dst6, MORPH_TOPHAT, kernel);
imshow("tophat", dst6);
}
void my_blackhat(int, void*) {
int s = step_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s));
morphologyEx(src, dst7, MORPH_BLACKHAT, kernel);
imshow("blackhat", dst7);
}
int main() {
src = imread("D:\\jing.png");
if (src.empty()) {
cerr << "open error" << endl;
return -1;
}
imshow("cat", src);
my_dilate(0, 0);
my_erode(0, 0);
my_open(0, 0);
my_close(0, 0);
my_gradient(0, 0);
my_tophat(0, 0);
my_blackhat(0, 0);
createTrackbar("erode_size", "erode", &step_size, max_size, my_erode);
createTrackbar("erode_size", "dilate", &step_size, max_size,my_dilate);
createTrackbar("erode_size", "open", &step_size, max_size, my_open);
createTrackbar("erode_size", "close", &step_size, max_size, my_close);
createTrackbar("erode_size", "gradient", &step_size, max_size, my_gradient);
createTrackbar("erode_size", "tophat", &step_size, max_size, my_tophat);
createTrackbar("erode_size", "blackhat", &step_size, max_size, my_blackhat);
waitKey(0);
}
原圖:
-
dilate
白點不斷變大
-
erode
白點逐漸變小
-
open
消除小物體;
在纖細處分離物體;
平滑較大的邊界並不明顯改變其面積
-
close
祛除小黑點
-
gradient
使輪廓更加清晰
-
頂帽
- 黑帽
好文章分享:
膨脹與腐蝕的徹底擊破:https://www.cnblogs.com/daxiongblog/p/6289551.html
學習 opencv—(10)形態學影象處理(2):開運算,閉運算,形態學梯度,頂帽,黒帽合輯 https://www.cnblogs.com/wyuzl/p/6266498.html(NICE)