更多形态学变换
更多形态学变换
目标
本文档尝试解答如下问题:
- 如何使用OpenCV函数 morphologyEx 进行形态学操作:
- 开运算 (Opening)
- 闭运算 (Closing)
- 形态梯度 (Morphological Gradient)
- 顶帽 (Top Hat)
- 黑帽(Black Hat)
原理
Note
以下内容来自于Bradski和Kaehler的大作 Learning OpenCV 。
前一节我们讨论了两种最基本的形态学操作:
- 腐蚀 (Erosion)
- 膨胀 (Dilation)
运用这两个基本操作,我们可以实现更高级的形态学变换。这篇文档将会简要介绍OpenCV提供的5种高级形态学操作:
开运算 (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"
#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";
/** 回调函数申明 */
void Morphology_Operations( int, void* );
/** @函数 main */
int main( int argc, char** argv )
{
/// 装载图像
src = imread( argv[1] );
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;
}
/**
* @函数 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 );
}
解释
-
看一下程序的总体流程:
-
装载图像
-
创建显示形态学操作的窗口
-
创建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]()













浙公网安备 33010602011771号