opencv图像的形态学变换

翻译:http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html#morphology-2

参考:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/opening_closing_hats/

opening_closing_hats.html#morphology-2

前一节我们讨论了两种最基本的形态学操作:

  • 腐蚀 (Erosion) 
  • 膨胀 (Dilation)

运用这两个基本操作,我们可以实现更高级的形态学变换。这篇文档将会简要介绍OpenCV提供的5种高级形态学操作:

如何使用OpenCV函数 morphologyEx 进行形态学操作:
  • 开运算 (Opening)
  • 闭运算 (Closing)
  • 形态梯度 (Morphological Gradient)
  • 顶帽 (Top Hat)
  • 黑帽(Black Hat)

morphologyEx

Performs advanced morphological transformations.

C++: 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() )
Python: cv2.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) → dst
C: void cvMorphologyEx(const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element, int operation, intiterations=1 )
Parameters:
  • src – Source image. The number of channels can be arbitrary. The depth should be one of CV_8U,CV_16UCV_16SCV_32F or CV_64F.
  • dst – Destination image of the same size and type as src .
  • kernel – Structuring element. It can be created using getStructuringElement().
  • anchor – Anchor position with the kernel. Negative values mean that the anchor is at the kernel center.
  • op –Type of a morphological operation that can be one of the following:
    • MORPH_OPEN - an opening operation
    • MORPH_CLOSE - a closing operation
    • MORPH_GRADIENT - a morphological gradient
    • MORPH_TOPHAT - “top hat”
    • MORPH_BLACKHAT - “black hat”
  • iterations – Number of times erosion and dilation are applied.
  • borderType – Pixel extrapolation method. See borderInterpolate for details.
  • borderValue – Border value in case of a constant border. The default value has a special meaning.

The function can perform advanced morphological transformations using an erosion and dilation as basic operations.

Opening operation:

\texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} ))

Closing operation:

\texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} ))

Morphological gradient:

\texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} )

“Top hat”:

\texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} )

“Black hat”:

\texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src}

Any of the operations can be done in-place. In case of multi-channel images, each channel is processed independently.

Note

  • An example using the morphologyEx function for the morphological opening and closing operations can be found at opencv_source_code/samples/cpp/morphology2.cpp

原理

开运算 (Opening)

开运算是通过先对图像腐蚀再膨胀实现的。

  • dst = open( src, element) = dilate( erode( src, element ) )

  • 能够排除小团块物体(假设物体较背景明亮)

  • 请看下面,左图是原图像,右图是采用开运算转换之后的结果图。 观察发现字母拐弯处的白色空间消失。

    Opening

闭运算(Closing)

  • 闭运算是通过先对图像膨胀再腐蚀实现的。

    dst = close( src, element ) = erode( dilate( src, element ) )

  • 能够排除小型黑洞(黑色区域)。

    Closing example

形态梯度(Morphological Gradient)

  • 膨胀图与腐蚀图之差

    dst = morph_{grad}( src, element ) = dilate( src, element ) - erode( src, element )

  • 能够保留物体的边缘轮廓,如下所示:

    Gradient

顶帽(Top Hat)

  • 原图像与开运算结果图之差

    dst = tophat( src, element ) = src - open( src, element )

    Top Hat

黑帽(Black Hat)

  • 闭运算结果图与原图像之差

    dst = blackhat( src, element ) = close( src, element ) - src

    Black Hat

源码

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"


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";

/** 回调函数申明 */
void Morphology_Operations( int, void* );

/** @函数 main */
int main( )
{
  /// 装载图像
  src = imread( "tupian.jpg" );

  if( !src.data )
  { return -1; }

 /// 创建显示窗口
 namedWindow( window_name, CV_WINDOW_AUTOSIZE );

 /// 创建选择具体操作的 trackbar
 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 );

 /// 创建选择内核形状的 trackbar
 createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,
                 &morph_elem, max_elem,
                 Morphology_Operations );

 /// 创建选择内核大小的 trackbar
 createTrackbar( "Kernel size:\n 2n +1", window_name,
                 &morph_size, max_kernel_size,
                 Morphology_Operations );

 /// 启动使用默认值
 Morphology_Operations( 0, 0 );

 waitKey(0);
 return 0;
 }

void Morphology_Operations( int, void* )
{
  // 由于 MORPH_X的取值范围是: 2,3,4,5 和 6
  int operation = morph_operator + 2;
  int morph_type;
  if(morph_elem =0){morph_type = MORPH_RECT : }
  else if(morph_elem = 1){morph_type = MORPH_CROSS;}
  else if(morph_elem = 2){morph_type = MORPH_ELLIPSE;}
  Mat element = getStructuringElement( morph_type, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );

  /// 运行指定形态学操作
  morphologyEx( src, dst, operation, element );
  imshow( window_name, dst );
  }

解释

  1. 看一下程序的总体流程:

    • 装载图像

    • 创建显示形态学操作的窗口

    • 创建3个trackbar获取用户参数:

      • 第一个trackbar “Operator” 返回用户选择的形态学操作类型 (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 );
        
      • 第二个trackbar “Element” 返回 morph_elem, 指定内核形状:

        createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,
                        &morph_elem, max_elem,
                        Morphology_Operations );
        
      • 第三个trackbar “Kernel Size” 返回内核大小(morph_size)

        createTrackbar( "Kernel size:\n 2n +1", window_name,
                        &morph_size, max_kernel_size,
                        Morphology_Operations );
        
    • 每当任一标尺被移动, 用户函数 Morphology_Operations 就会被调用,该函数获取trackbar的当前值运行指定操作并更新显示结果图像。

       /**
        * @函数 Morphology_Operations
        */
      void Morphology_Operations( int, void* )
      {
        // 由于 MORPH_X的取值范围是: 2,3,4,5 和 6
        int operation = morph_operator + 2;
      
        Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
      
        /// 运行指定形态学操作
        morphologyEx( src, dst, operation, element );
        imshow( window_name, dst );
       }
      

      运行形态学操作的核心函数是 morphologyEx 。在本例中,我们使用了4个参数(其余使用默认值):

      • src : 原 (输入) 图像
      • dst: 输出图像
      • operation: 需要运行的形态学操作。 我们有5个选项:
        • 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: 内核,可以使用函数:get_structuring_element:getStructuringElement <> 自定义。

结果

  • 在编译上面的代码之后, 我们可以运行结果,将图片路径输入。这里使用图像: baboon.png:

    Morphology 2: Original image
  • 这里是显示窗口的两个截图。第一幅图显示了使用交错内核和 开运算 之后的结果, 第二幅图显示了使用椭圆内核和 黑帽 之后的结果。

    Morphology 2: Result sample

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值