上一节中,我们重点了解了腐蚀和膨胀者两种基本的形态操作,而运用这两种基本操作, 可以实现更高级的形态学变化。
所以,本节的主角是PHPOpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术, 来执行更高级的形态学变换,如开闭运算、形态学梯度、“顶帽”、“黑帽”等。
首先,我们需要知道,形态学的高级形态,往往都是简历在腐蚀和膨胀者两个基本操作智商的。 而关于腐蚀和膨胀,概念和细节以及相关代码请参考上一小节。对膨胀和腐蚀心中有数了。接 下来的高级形态学操作,应该就不难理解。
开运算 开运算(Opening Operation),其实上就是先腐蚀后膨胀的过程。其数学表示式如下:
 dst = open(src,element) = dilate(erode(src,element))
开运算可以用来消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同事不明显 改变其面积。原始图和结果图如下:
闭运算 先膨胀后再腐蚀的过程称为闭运算(Closing Operation),其数学表达式如下:
 dst = close(src,element) = erode(dilate(src,element))
闭运算能够排除小型黑洞(黑色区域)。原始图和效果图如下:
形态学梯度 形态学梯度(Morphological Gradient)是膨胀图和腐蚀图之差,数学表示式如下:
 dst=morph-grad(src,element) = dilate(src,element)−erode(src,element)
对二值图像进行这一操作可以将团块(blob)的边缘突出出来。我们可以用形态学梯度来保留物体的 边缘轮廓,如下图:
顶帽 顶帽运算(Top Hat)又常常被译为“礼帽”运算,是原图像与上文刚刚介绍的“开运算”的结果图之差, 数学表达式如下:
 dst=tophat(src,element)=src−open(src,element)
因为开运算带来的结果是放大了裂缝或者局部低亮度的区域。因此,从原图中减去开运算后的图,得
到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作与选择的核大小有关。
顶帽运算往往用来分离比邻近点亮一些的板块。在一副图像具有大幅的背景,而微小物品比较有规律的情况下,
可以使用顶帽运算进行背景提取。
黑帽 黑帽(Black Hat)运算是闭运算的结果图与原图像之差。数学表达式为:
 dst=blackhat(src,element)=close(src,element)−src
黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核大小相关。
所以,黑帽运算用来分离比邻近点暗一些的斑块,效果图有着非常完美的轮廓。
综合示例 代码 use  CV \Size ;use  CV \Point ;use  function  CV \{    getStructuringElement , morphologyEx , imshow , namedWindow ,     createTrackbar , getTrackBarPos , waitKey  }; use  function  CV \imread ;use  const  CV \{    IMREAD_COLOR , WINDOW_AUTOSIZE  }; $src = null ; $dst = null ; $morph_elem = 0 ; $morph_size = 0 ; $morph_operator = 0 ; const  max_operator = 4 ;const  max_elem = 2 ;const  max_kernel_size = 21 ;const  window_name = "Morphology Transformations Demo" ;const  morphOperatorTrackBarName = "Operator:0: Opening - 1: Closing  \n 2: Gradient - 3: Top Hat \n 4: Black Hat" ;const  morphElemTrackBarName = "Element:\n 0: Rect - 1: Cross - 2: Ellipse" ;const  morphSizeTrackBarName = "Kernel size:\n 2n +1" ;$Morphology_Operations = function  ()   {     global  $morph_operator;     global  $morph_elem;     global  $morph_size;     global  $src;     global  $dst;     $morph_operator = getTrackBarPos(morphOperatorTrackBarName, window_name);     $morph_elem = getTrackBarPos(morphElemTrackBarName, window_name);     $morph_size = getTrackBarPos(morphSizeTrackBarName, window_name);               $operation = $morph_operator + 2 ;          $element = getStructuringElement($morph_elem, new  Size(2  * $morph_size + 1 , 2  * $morph_size + 1 ), new  Point($morph_size, $morph_size));          morphologyEx($src, $dst, $operation, $element);     imshow(window_name, $dst); }; function  run ()  {    global  $src;     global  $Morphology_Operations;     global  $morph_operator;     global  $morph_elem;     global  $morph_size;     $src = imread('baboon.jpg' , IMREAD_COLOR);      if  ($src->empty()) {         return  false ;     }     namedWindow(window_name, WINDOW_AUTOSIZE);           createTrackbar(morphOperatorTrackBarName, window_name,         $morph_operator, max_operator,         $Morphology_Operations);          createTrackbar(morphElemTrackBarName, window_name,         $morph_elem, max_elem,         $Morphology_Operations);          createTrackbar(morphSizeTrackBarName, window_name,         $morph_size, max_kernel_size,         $Morphology_Operations);     imshow(window_name, $src);     waitKey(0 );     return  true ; } run(); 
 
运行结果 
代码下载地址 下载地址