opencv 其他形态学变换
- 如何使用OpenCV函數(shù)?morphologyEx?進(jìn)行形態(tài)學(xué)操作:
- 開(kāi)運(yùn)算 (Opening)
- 閉運(yùn)算 (Closing)
- 形態(tài)梯度 (Morphological Gradient)
- 頂帽 (Top Hat)
- 黑帽(Black Hat)
原理
Note
?以下內(nèi)容來(lái)自于Bradski和Kaehler的大作?Learning OpenCV?。
前一節(jié)我們討論了兩種最基本的形態(tài)學(xué)操作:
- 腐蝕 (Erosion)
- 膨脹 (Dilation)
運(yùn)用這兩個(gè)基本操作,我們可以實(shí)現(xiàn)更高級(jí)的形態(tài)學(xué)變換。這篇文檔將會(huì)簡(jiǎn)要介紹OpenCV提供的5種高級(jí)形態(tài)學(xué)操作:
開(kāi)運(yùn)算 (Opening)
-
開(kāi)運(yùn)算是通過(guò)先對(duì)圖像腐蝕再膨脹實(shí)現(xiàn)的。
-
能夠排除小團(tuán)塊物體(假設(shè)物體較背景明亮)
-
請(qǐng)看下面,左圖是原圖像,右圖是采用開(kāi)運(yùn)算轉(zhuǎn)換之后的結(jié)果圖。 觀察發(fā)現(xiàn)字母拐彎處的白色空間消失。
閉運(yùn)算(Closing)
-
閉運(yùn)算是通過(guò)先對(duì)圖像膨脹再腐蝕實(shí)現(xiàn)的。
-
能夠排除小型黑洞(黑色區(qū)域)。
形態(tài)梯度(Morphological Gradient)
-
膨脹圖與腐蝕圖之差
-
能夠保留物體的邊緣輪廓,如下所示:
頂帽(Top Hat)
-
原圖像與開(kāi)運(yùn)算結(jié)果圖之差
黑帽(Black Hat)
-
閉運(yùn)算結(jié)果圖與原圖像之差
源碼
下面是本教程的源碼, 你也可以從?這里?下載。
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdlib.h> #include <stdio.h>using namespace cv;/// 全局變量 Mat src, dst;int morph_elem = 0; int morph_size = 0; int morph_operator = 0; int const max_operator = 4; int const max_elem = 2; int const max_kernel_size = 21;char* window_name = "Morphology Transformations Demo";/** 回調(diào)函數(shù)申明 */ void Morphology_Operations( int, void* );/** @函數(shù) main */ int main( int argc, char** argv ) {/// 裝載圖像src = imread( argv[1] );if( !src.data ){ return -1; }/// 創(chuàng)建顯示窗口namedWindow( window_name, CV_WINDOW_AUTOSIZE );/// 創(chuàng)建選擇具體操作的 trackbarcreateTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", window_name, &morph_operator, max_operator, Morphology_Operations );/// 創(chuàng)建選擇內(nèi)核形狀的 trackbarcreateTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,&morph_elem, max_elem,Morphology_Operations );/// 創(chuàng)建選擇內(nèi)核大小的 trackbarcreateTrackbar( "Kernel size:\n 2n +1", window_name,&morph_size, max_kernel_size,Morphology_Operations );/// 啟動(dòng)使用默認(rèn)值Morphology_Operations( 0, 0 );waitKey(0);return 0;}/** * @函數(shù) Morphology_Operations */ void Morphology_Operations( int, void* ) {// 由于 MORPH_X的取值范圍是: 2,3,4,5 和 6int operation = morph_operator + 2;Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );/// 運(yùn)行指定形態(tài)學(xué)操作morphologyEx( src, dst, operation, element );imshow( window_name, dst );}解釋
看一下程序的總體流程:
-
裝載圖像
-
創(chuàng)建顯示形態(tài)學(xué)操作的窗口
-
創(chuàng)建3個(gè)trackbar獲取用戶(hù)參數(shù):
-
第一個(gè)trackbar?“Operator”?返回用戶(hù)選擇的形態(tài)學(xué)操作類(lèi)型 (morph_operator).
createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat",window_name, &morph_operator, max_operator,Morphology_Operations ); -
第二個(gè)trackbar?“Element”?返回?morph_elem, 指定內(nèi)核形狀:
createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,&morph_elem, max_elem,Morphology_Operations ); -
第三個(gè)trackbar?“Kernel Size”?返回內(nèi)核大小(morph_size)
createTrackbar( "Kernel size:\n 2n +1", window_name,&morph_size, max_kernel_size,Morphology_Operations );
-
-
每當(dāng)任一標(biāo)尺被移動(dòng), 用戶(hù)函數(shù)?Morphology_Operations?就會(huì)被調(diào)用,該函數(shù)獲取trackbar的當(dāng)前值運(yùn)行指定操作并更新顯示結(jié)果圖像。
/** * @函數(shù) Morphology_Operations */ void Morphology_Operations( int, void* ) {// 由于 MORPH_X的取值范圍是: 2,3,4,5 和 6int operation = morph_operator + 2;Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );/// 運(yùn)行指定形態(tài)學(xué)操作morphologyEx( src, dst, operation, element );imshow( window_name, dst );}運(yùn)行形態(tài)學(xué)操作的核心函數(shù)是?morphologyEx?。在本例中,我們使用了4個(gè)參數(shù)(其余使用默認(rèn)值):
- src?: 原 (輸入) 圖像
- dst: 輸出圖像
- operation: 需要運(yùn)行的形態(tài)學(xué)操作。 我們有5個(gè)選項(xiàng):
- Opening: MORPH_OPEN : 2
- Closing: MORPH_CLOSE: 3
- Gradient: MORPH_GRADIENT: 4
- Top Hat: MORPH_TOPHAT: 5
- Black Hat: MORPH_BLACKHAT: 6
你可以看到, 它們的取值范圍是 <2-6>, 因此我們要將從tracker獲取的值增加(+2):
int operation = morph_operator + 2;- element: 內(nèi)核,可以使用函數(shù):get_structuring_element:getStructuringElement <>?自定義。
結(jié)果
-
在編譯上面的代碼之后, 我們可以運(yùn)行結(jié)果,將圖片路徑輸入。這里使用圖像:?baboon.png:
-
這里是顯示窗口的兩個(gè)截圖。第一幅圖顯示了使用交錯(cuò)內(nèi)核和?開(kāi)運(yùn)算?之后的結(jié)果, 第二幅圖顯示了使用橢圓內(nèi)核和?黑帽?之后的結(jié)果。
總結(jié)
以上是生活随笔為你收集整理的opencv 其他形态学变换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: opencv 图像的腐蚀与膨胀
- 下一篇: opencv 图像阈值分割图像