数学形态学(Mathematical morphology) 是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat 变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。
一.形态学操作API函数接口
void cv::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()
)
---------------------------------------------------------------------------------------------------------------------------------
参数说明:
(1)InputArray类型的src,输入图像。通道数可以任意,但深度应为CV_8U、CV_16U、 CV_16S、CV_32F或CV_64F之一。
(2)OutputArray类型的dst,即目标图像,与输入图像有相同的尺寸和类型。
(3)int类型的op,形态学操作的类型,请参见cv::MorphTypes
(4)InputArray类型的kernel,用于膨胀的结构元素;如果elemenat=Mat(),则使用3 x 3矩形结构元素。可以使用getStructuringElement创建内核。
(5)Point类型的anchor:锚定在元素中的位置;默认值(-1,-1)表示锚定在元素中心。
(6)int类型的iterations:应用膨胀的次数。
(7)int类型的borderType:像素外推方法,参见cv::BorderTypes。
(8)Scalar类型的borderValue:恒定边框时的边框值。
cv::MorphTypes结构体内容如下:
enum MorphTypes{
MORPH_ERODE = 0, //腐蚀
MORPH_DILATE = 1, //膨胀
MORPH_OPEN = 2, //开操作
MORPH_CLOSE = 3, //闭操作
MORPH_GRADIENT = 4, //梯度操作
MORPH_TOPHAT = 5, //顶帽操作
MORPH_BLACKHAT = 6, //黑帽操作
};
-------------------------------------------------------------------------------------------------------------------
二.形态学操作——顶帽变换,底帽变换,形态学梯度
(1)顶帽变换
图像减去开运算结果称为顶帽变换(Top-hat)。开运算可以消除暗背景下的较亮区域,那么如果用原图减去开运算结果就可以得到原图中灰度较亮的区域,所以又称白顶帽变换。它还有一个很重要的作用,就是校正不均匀光照。
# 顶帽运算
dst = cv2.morphologyEx(img1, cv2.MORPH_TOPHAT, kernel)
(2)底帽变换
图像减去闭运算结果称为底帽变换(Bottom-hat)。闭运算可以删除亮度较高背景下的较暗区域,那么用原图减去闭运算结果就可以得到原图中灰度较暗的区域,所以又称黑底帽变换。
#底帽运算
dst = cv2.morphologyEx(img, MORPH_BLACKHAT, kernel)
(3)形态学梯度
形态学梯度,膨胀的结果减去腐蚀的结果,因为膨胀是取邻域内的最大值,从而增大亮度高的区域的面积,而腐蚀是取邻域内的最小值,从而减小亮度高的区域的面积,所以得到的图像是图像中物体的边界。膨胀结果减去腐蚀结果,可以得到图像中物体的边界,是一种提取目标物体边缘的算法。
# 梯度运算
dst = cv2.cv2.morphologyEx(img1, cv2.MORPH_GRADIENT, kernel)
---------------------------------------------------------------------------------------------------------------------------------
总结
腐蚀和膨胀是最基本的形态学算子
(1)腐蚀:删除对象边界的某些像素。粗略的说,腐蚀可以使目标区域范围“变小”,其实质造成图像的边界收缩,可以用来消除小且无意义的目标物。
(2)膨胀:给图像中的对象边界添加像素。粗略地说,膨胀会使目标区域范围“变大”,使目标边界向外部扩张,可以用来填补目标区域中某些空洞以及消除包含在目标区域中的小颗粒噪声。
高级形态学变换:
(1)开运算: 先腐蚀再膨胀,能去除原图像的毛刺
(2)闭运算: 先膨胀再腐蚀,可清除小黑点
(3)梯度:膨胀图-腐蚀图,提取物体边缘
(4)顶/礼帽:原图像-开运算图,突出原图像中比周围亮的区域
(5)黑帽:闭运算图-原图像,突出原图像中比周围暗的区域
=========================================================================
代码实现:
#include"stdafx.h"
#include<opencv2\imgproc\types_c.h>
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat image1 = imread("F:/photo/qx.jpg", 1);
namedWindow("input_picture1");
imshow("input_picture1", image1);
Mat image2;
Mat image3;
cvtColor(image1, image2, COLOR_RGB2GRAY);
namedWindow("input_picture2");
imshow("input_picture2", image2);
threshold(image2, image3, 65, 255, THRESH_BINARY);
namedWindow("input_picture3");
imshow("input_picture3", image3);
Mat dst;
Mat kernel = getStructuringElement(MORPH_RECT, Size(7, 7), Point(-1, -1));
//开操作
//morphologyEx(image3, dst, CV_MOP_OPEN, kernel);
//imshow("open-src", dst);
//闭操作
//morphologyEx(image3, dst, CV_MOP_CLOSE, kernel);
//imshow("close-src", dst);
//形态学梯度
morphologyEx(image3, dst, CV_MOP_GRADIENT, kernel);
imshow("gradient-src", dst);
//顶帽
morphologyEx(image3, dst, CV_MOP_TOPHAT, kernel);
imshow("tophat-src", dst);
//黑帽
morphologyEx(image3, dst, CV_MOP_BLACKHAT, kernel);
imshow("blackhat-src", dst);
waitKey(0);
return 0;
}
图像处理效果图:
原图与灰度图
灰度图与二值化图像
形态学操作和黑帽操作
顶帽操作和黑帽操作