OpenCV学习笔记(八):形态学morpholgy(2):开/闭运算,形态学梯度、顶帽/黑帽morphologyEx()
OpenCV學習筆記(八):形態學morpholgy(2):開、閉運算,形態學梯度、頂帽、黑帽:morphologyEx()
數學形態學(Mathematical morphology) 是一門建立在格論和拓撲學基礎之上的圖像分析學科,是數學形態學圖像處理的基本理論。其基本的運算包括:二值腐蝕和膨脹、二值開閉運算、骨架抽取、極限腐蝕、擊中擊不中變換、形態學梯度、Top-hat變換、顆粒分析、流域變換、灰值腐蝕和膨脹、灰值開閉運算、灰值形態學梯度等。
一、開運算(Opening Operation)
其實就是先腐蝕后膨脹的過程:
開運算可以用來消除小物體、在纖細點處分離物體、平滑較大物體的邊界的同時并不明顯改變其面積。
二、閉運算(Closing Operation)
先膨脹后腐蝕的過程:
閉運算能夠排除小型黑洞(黑色區域),可以將團塊的邊緣突出出來。
三、形態學梯度(Morphological Gradient)
膨脹圖與腐蝕圖之差:
對二值圖像進行這一操作可以將團塊(blob)的邊緣突出出來。我們可以用形態學梯度來保留物體的邊緣輪廓。
四、頂帽(Top Hat)
頂帽運算(Top Hat)又常常被譯為”禮帽“運算,源圖與“開運算圖“之差:
因為開運算帶來的結果是放大了裂縫或者局部低亮度的區域,因此,從原圖中減去開運算后的圖,得到的效果圖突出了比原圖輪廓周圍的區域更明亮的區域,所以頂帽運算往往用來分離比鄰近點亮一些的斑塊。當一幅圖像具有大幅的背景的時候,而微小物品比較有規律的情況下,可以使用頂帽運算進行背景提取。
五、黑帽(Black Hat)
為”閉運算“的結果圖與原圖像之差:
黑帽運算后的效果圖突出了比原圖輪廓周圍的區域更暗的區域,黑帽運算用來分離比鄰近點暗一些的斑塊。
六、morphologyEx函數詳解:
C++: void morphologyEx( InputArray src, OutputArray dst, int op, InputArraykernel, Pointanchor=Point(-1,-1), intiterations=1, intborderType=BORDER_CONSTANT, constScalar& borderValue=morphologyDefaultBorderValue() );第一個參數,InputArray類型的src,輸入圖像,即源圖像,(CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F)。
第二個參數,OutputArray類型的dst,即目標圖像。
第三個參數,int類型的op,表示形態學運算的類型:
第五個參數,Point類型的anchor,錨的位置,其有默認值(-1,-1),表示錨位于中心。
第六個參數,int類型的iterations,迭代使用函數的次數,默認值為1。
第七個參數,int類型的borderType,用于推斷圖像外部像素的某種邊界模式。注意它有默認值BORDER_ CONSTANT。
第八個參數,const Scalar&類型的borderValue,當邊界為常數時的邊界值,有默認值morphologyDefaultBorderValue(),一般我們不用去管他。需要用到它時,可以看官方文檔中的createMorphologyFilter()函數得到更詳細的解釋。
getStructuringElement函數相關的調用示例代碼如下
//結構元素(內核矩陣)的尺寸 int g_nStructElementSize = 3;//獲取自定義核 Mat element =getStructuringElement(MORPH_RECT,Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),Point(g_nStructElementSize, g_nStructElementSize ));第一個參數表示內核的形狀,我們可以選擇如下三種形狀之一
矩形: MORPH_RECT 交叉形: MORPH_CROSS 橢圓形: MORPH_ELLIPSE第二和第三個參數分別是內核的尺寸以及錨點的位置,對于錨點的位置,有默認值Point(-1,-1),表示錨點位于中心
六、示例代碼:
#include <opencv2/opencv.hpp>using namespace cv; using namespace std;Mat g_srcImage, g_dstImage; //原始圖和效果圖 int g_nElementShape = MORPH_RECT; //元素結構的形狀//變量接收的TrackBar位置參數 int g_nMaxIterationNum = 10; // 最大方向值 int g_nOpenCloseNum = 0; // 開閉/運算內核值 int g_nTopBlackHatNum = 0; // 頂帽/黑帽內核值int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 1、載入原圖g_srcImage = imread("F:/C++/2. OPENCV 3.1.0/TEST/綜合.png");if( !g_srcImage.data ) { printf("Oh,no,讀取srcImage錯誤~! \n"); return false; }// 2、顯示原始圖namedWindow("【原始圖】");imshow("【原始圖】", g_srcImage);// 3、創建窗口namedWindow("【開運算/閉運算】",1);namedWindow("【頂帽/黑帽】",1);// 4、參數賦值g_nOpenCloseNum=9;g_nTopBlackHatNum=10;// 5、分別為二個窗口創建滾動條createTrackbar("迭代值", "【開運算/閉運算】",&g_nOpenCloseNum,g_nMaxIterationNum*2+1,on_OpenClose);createTrackbar("迭代值", "【頂帽/黑帽】",&g_nTopBlackHatNum,g_nMaxIterationNum*2+1,on_TopBlackHat);// 6、輪詢獲取按鍵信息while(1){//執行回調函數on_OpenClose(g_nOpenCloseNum, 0);on_TopBlackHat(g_nTopBlackHatNum,0);//獲取按鍵int c = waitKey(0);//按下鍵盤按鍵Q或者ESC,程序退出if( (char)c == 'q'||(char)c == 27 )break;//按下鍵盤按鍵1,使用橢圓(Elliptic)結構元素結構元素MORPH_ELLIPSEif( (char)c == 49 )//鍵盤按鍵1的ASII碼為49g_nElementShape = MORPH_ELLIPSE;//按下鍵盤按鍵2,使用矩形(Rectangle)結構元素MORPH_RECTelse if( (char)c == 50 )//鍵盤按鍵2的ASII碼為50g_nElementShape = MORPH_RECT;//按下鍵盤按鍵3,使用十字形(Cross-shaped)結構元素MORPH_CROSSelse if( (char)c == 51 )//鍵盤按鍵3的ASII碼為51g_nElementShape = MORPH_CROSS;//按下鍵盤按鍵space,在矩形、橢圓、十字形結構元素中循環else if( (char)c == ' ' )g_nElementShape = (g_nElementShape + 1) % 3;}return a.exec(); }1)開運算/閉運算 回調函數
static void on_OpenClose(int, void*) {//偏移量的定義int offset = g_nOpenCloseNum - g_nMaxIterationNum; //偏移量int Absolute_offset = offset > 0 ? offset : -offset;//偏移量絕對值//自定義核Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset) );//進行操作if( offset < 0 )// 偏移量小于0 時,開運算morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);else if (offset == 0)g_srcImage.copyTo(g_dstImage);else// 偏移量大于0 時,閉運算morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);//顯示圖像imshow("【開運算/閉運算】",g_dstImage); }2)頂帽運算/黑帽運算 回調函數
static void on_TopBlackHat(int, void*) {//偏移量的定義int offset = g_nTopBlackHatNum - g_nMaxIterationNum;//偏移量int Absolute_offset = offset > 0 ? offset : -offset;//偏移量絕對值//自定義核Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(-1, -1) );//進行操作if( offset < 0 )morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT , element);else if (offset == 0)g_srcImage.copyTo(g_dstImage);elsemorphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);//顯示圖像imshow("【頂帽/黑帽】",g_dstImage); }結果:
MORPH_ELLIPSE
MORPH_RECT
MORPH_CROSS
總結
以上是生活随笔為你收集整理的OpenCV学习笔记(八):形态学morpholgy(2):开/闭运算,形态学梯度、顶帽/黑帽morphologyEx()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pytorch查看模型的可训练参数
- 下一篇: 使用Hadoop自带的例子wordcou