- 应用两个非常常见的形态运算符:侵蚀和扩张。为此,您将使用以下OpenCV功能:
-
形态作业
- 简而言之:一组基于形状处理图像的操作。形态操作将结构元素应用于输入图像并生成输出图像。
- 最基本的形态作用是:侵蚀和扩张。它们有广泛的用途,即:
- 消除噪音
- 隔离单个元素并连接图像中的不同元素。
- 查找图像中的强度凸点或孔
- 我们将简要解释膨胀和侵蚀,使用以下图像作为示例:
-
扩张
- 该操作包括将图像与某些内核(B)进行卷积,其可以具有任何形状或尺寸,通常为正方形或圆形。AB
- 内核具有定义的锚点,通常是内核的中心。B
- 当内核在图像上扫描时,我们计算由B重叠的最大像素值,并用该最大值替换锚点位置中的图像像素。您可以推断,这种最大化的操作会使图像中的亮区“增长”(因此称为扩张)。以上图为例。应用扩张我们可以得到:BB
-
背景(明亮)扩大了字母的黑色地区。
为了更好地把握想法并避免可能的混乱,在另一个例子中,我们已经将原始图像倒过来,如白色的对象现在是这个字母。我们已经执行了两个具有大小的矩形结构元素的扩张3x3。
左图:原图反转,右图:产生扩张
膨胀使物体变白。
侵蚀
- 这个操作是扩张的姊妹。它计算给定内核区域的局部最小值。
- 当内核在图像上扫描时,我们计算由重叠的最小像素值,并用该最小值替换锚点下的图像像素。BB
- 对于扩张的例子,我们可以将侵蚀算子应用于原始图像(如上所示)。您可以在下面的结果中看到,图像的明亮区域(背景,显然)变得更薄,而黑暗区域(“写作”)变得更大。
-
以相似的方式,通过对反转的原始图像(具有尺寸的矩形结构元素的两次侵蚀)施加侵蚀操作来产生相应的图像3x3:
左图:原图反转,右图:造成侵蚀
侵蚀使物体变白。
代码实现:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
Mat src, dst;
char OUTPUT_WIN[] = "output image";
int element_size = 3;
int max_size = 21;
void CallBack_Demo(int, void*);
int main(int argc, char** argv) {
src = imread("C:/usr/opencv-test/Testpictures/sight.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);
createTrackbar("Element Size :", OUTPUT_WIN, &element_size, max_size, CallBack_Demo);
CallBack_Demo(0, 0);
waitKey(0);
return 0;
}
void CallBack_Demo(int, void*) {
int s = element_size * 2 + 1;
Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));
dilate(src, dst, structureElement, Point(-1, -1), 1); //膨胀
//erode(src, dst, structureElement); //腐蚀
imshow(OUTPUT_WIN, dst);
return;
}