Python 形态打开和关闭产生相同结果的情况?

Python 形态打开和关闭产生相同结果的情况?,python,matlab,opencv,image-processing,computer-vision,Python,Matlab,Opencv,Image Processing,Computer Vision,我想知道是否有任何例子或情况下,打开和关闭一个单一的图像形态学操作产生相同的结果 例如,假设我们有一个图像X,我们已经完成了打开操作来生成Y。同样,我们对原始的X执行了关闭操作,以生成相同的Y。我想知道是否有这些类型图像的示例X。也欢迎使用Python或MATLAB编程示例。是的,有这样的图像。开运算的一个性质(例如,在文章中提到过)是一个反扩展运算,即如果Y是X的开运算,那么Y⊆ X.同样,关闭是一个广泛的操作(即X⊆ Y) ,因此对于任何这样的图像X=Y。任何对打开和关闭都不变的图像都将满足

我想知道是否有任何例子或情况下,打开和关闭一个单一的图像形态学操作产生相同的结果


例如,假设我们有一个图像
X
,我们已经完成了打开操作来生成
Y
。同样,我们对原始的
X
执行了关闭操作,以生成相同的
Y
。我想知道是否有这些类型图像的示例
X
。也欢迎使用Python或MATLAB编程示例。

是的,有这样的图像。开运算的一个性质(例如,在文章中提到过)是一个反扩展运算,即如果Y是X的开运算,那么Y⊆ X.同样,关闭是一个广泛的操作(即X⊆ Y) ,因此对于任何这样的图像X=Y。任何对打开和关闭都不变的图像都将满足您的要求(并且,正如我刚才所示,只有这样的图像才会满足)


具体示例取决于进行侵蚀或膨胀时使用的结构元素。例如,如果它是一个所有元素都等于1的正方形nxn矩阵,那么任何高度和宽度都大于n(并且距离图像边缘足够远,即至少有n/2个像素)的矩形都将满足此要求。

是的。举一个小例子,如果你有一个二值图像,它由一堆不连续且不同的正方形组成。如果指定的结构元素为正方形,并选择结构元素使其小于图像中的最小正方形,则执行任一操作都会得到相同的结果

如果在此图像上打开并关闭,则会产生相同的结果。记住,开口是先腐蚀后膨胀,而闭合是先膨胀后腐蚀。在分析形状时,侵蚀会略微缩小图像区域,而膨胀会略微放大图像区域

通过先进行侵蚀,然后进行扩张(打开),可以缩小对象,然后再使其生长。这将使图像恢复到以前的状态,前提是您像我们之前讨论的那样选择结构元素。类似地,如果先进行膨胀,然后进行侵蚀(闭合),则会使对象变大,然后再次缩小,也会使图像恢复到原来的位置。。。当然,遵循我刚才提到的同样的指导方针

如果要选择比最小对象大的结构元素,则打开将从图像中删除该对象,因此无法恢复原始图像。此外,您还需要确保对象彼此远离,并且在滑动和执行形态学操作时,结构元素的大小不会与任何对象重叠。原因是如果你要做一个闭包,你会把这两个对象连接在一起,这样也不会得到相同的结果


下面是我生成的一个二进制图像示例:

要在MATLAB中生成此图像,可以执行以下操作:

A = false(200,200);
A(30:60,30:60) = true;
A(90:110,90:110) = true;
A(10:30, 135:155) = true;
A(150:180,100:120) = true;
在Python中,可以使用
numpy

import numpy as np
A = np.zeros((200,200), dtype='uint8')
A[29:60,29:60] = 255
A[89:110,89:110] = 255
A[9:30, 134:155] = 255
A[149:180, 99:120] = 255
我之所以必须在
numpy
中创建数组作为
uint8
,是因为当我们要显示此图像时,我将使用OpenCV,它要求图像至少是
uint8
类型

现在,让我们选择一个5 x 5的正方形结构元素,让我们用这个图像执行一个关闭和一个打开。我们将以从左到右的单个图形显示结果:

se = strel('square', 5);
A_close = imclose(A, se);
A_open = imopen(A, se);
figure;
subplot(1,3,1);
imshow(A);
title('Original');
subplot(1,3,2);
imshow(A_close);
title('Closed');
subplot(1,3,3);
imshow(A_open);
title('Open');
结果是:

看起来确实一样!为了真正显示差异,让我们从原始图像中减去关闭和打开的结果。如果它们都与原始图像相同,那么最终应该得到一个空白图像

figure;
subplot(1,2,1);
imshow(abs(double(A) - double(A_close)));
subplot(1,2,2);
imshow(abs(double(A) - double(A_open)));
请记住,我将图像转换为
double
以便于减法,并使用
abs
以确保反映负差异。这就是我得到的:

正如您所看到的,两个结果都是完全空白的,这意味着它们是每个结果之后原始图像的精确副本

第一部分的Python等效代码如下所示:

import cv2
se = np.ones((5,5), dtype='uint8')
A_close = cv2.morphologyEx(A, cv2.MORPH_CLOSE, se)
A_open = cv2.morphologyEx(A, cv2.MORPH_OPEN, se)
cv2.imshow('Original', A)
cv2.imshow('Close', A_close)
cv2.imshow('Open', A_open)
cv2.waitKey(0)
cv2.destroyAllWindows()
以下是我得到的:

您需要为此Python代码安装OpenCV包。我将所有图像显示为三个单独的图形,然后将窗口留在那里,直到您选择其中任何一个并按下一个键。完成此操作后,所有窗口都将关闭。如果您想显示减法内容,以下是Python中的代码:

A_close_diff = A - A_close
A_open_diff = A - A_open
cv2.imshow('Close Diff', A_close_diff)
cv2.imshow('Open Diff', A_open_diff)
cv2.waitKey(0)
cv2.destroyAllWindows()
我没有在MATLAB中命名这些图形,因为我们展示的是显而易见的,但是对于OpenCV,您需要命名窗口,所以我为每个窗口命名,描述我们展示的内容。我也不需要取绝对值,因为在
numpy
中,执行导致溢出或下溢的算术运算只会将其自身包裹起来,而对于MATLAB,值会被剪裁。这就是为什么对于MATLAB,我需要转换为双精度,并取绝对值,因为
imshow
不显示负强度,或者如果我们的情况是
0-1
,输出将为0,并且您无法显示此位置有差异。对于Python,对
uint8
执行
0-1
,结果将是255,因此我们肯定可以在这里看到不同。。。。所以不需要像我们在MATLAB中做的那样,做任何这方面的工作。以下是我得到的:


一般来说,你可以复制我对任何形状和大小的形状所做的,只要你选择一个结构元素,模仿你图像中形状的属性,然后选择一个结构元素