Python 选择正确的结构元素

Python 选择正确的结构元素,python,opencv,image-processing,image-morphology,Python,Opencv,Image Processing,Image Morphology,我正在创建一个程序,自动将太阳能电池与光伏组件分离,我首先使用自适应阈值对图像进行阈值化,以获得以下图像 在此之后,我打算通过使用一个大小为(10,10)的椭圆结构元素的膨胀来移除单元格边界内的黑色像素,并获得以下图像 正如您所看到的,仍然有一些黑色像素,现在如果我增加结构元素的大小,我将丢失单元格边界 我尝试了其他可用的结构元素,如cross和矩形,但没有成功,因此我需要定义一个自定义内核,而不知道如何定义一个 import numpy as np import cv2 img=cv2.

我正在创建一个程序,自动将太阳能电池与光伏组件分离,我首先使用自适应阈值对图像进行阈值化,以获得以下图像

在此之后,我打算通过使用一个大小为(10,10)的椭圆结构元素的膨胀来移除单元格边界内的黑色像素,并获得以下图像

正如您所看到的,仍然有一些黑色像素,现在如果我增加结构元素的大小,我将丢失单元格边界

我尝试了其他可用的结构元素,如cross和矩形,但没有成功,因此我需要定义一个自定义内核,而不知道如何定义一个

import numpy as np
import cv2
img=cv2.imread('result2.jpg',0)
th1 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,25,-2)
kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(15,15))
closing = cv2.morphologyEx(th1, cv2.MORPH_CLOSE, kernel)
cv2.imwrite('closing.jpg',closing)
cv2.imwrite('threshold.jpg',th1)
cv2.waitKey(0)
cv2.destroyAllWindows()

我的第一条建议是不要马上进入门槛。阈值化是您希望在最后以这种方式进行的事情。阈值化丢弃了有价值的信息。形态学操作也适用于灰度图像

选择正确的形态学操作符来只保留您感兴趣的形状实际上是非常直观的。在这种情况下,您希望同时保持水平线和垂直线。让我们使用线条结构元素。线条是黑色的,因此我们使用结束符来删除看起来与线条不一样的东西

用垂直线闭合将删除所有水平线,用水平线闭合将删除所有垂直线。那么如何将这两者结合起来呢?事实证明,两次关闭的下确界(像素最小值)也是一个关闭。因此,垂直线闭合和水平线闭合的下确界是两条线同时闭合,您将保留这两条线中任何一条适合的形状

这里有一个例子。我正在使用(我没有OpenCV)

您可以尝试稍微调整一下,添加一些额外的处理,并在末尾添加自适应阈值,以获得光伏电池的边缘。但实际上有一个更好的方法来找到这些

我在这里利用了这样一个事实,面板是如此的笔直,它覆盖了整个图像。我们可以简单地沿行和列进行平均投影:

x = dip.Mean(out, process=[1, 0]).Squeeze()
y = dip.Mean(out, process=[0, 1]).Squeeze()
import matplotlib.pyplot as pp
pp.subplot(2,1,1)
pp.plot(x)
pp.subplot(2,1,2)
pp.plot(y)
pp.show()


从这些投影中检测细胞的边缘应该是相当直接的。

我添加了原始图像。槽对应于细胞边界,因此我需要13个槽对应于列,7个槽对应于行,因为沿列有12个细胞,沿行有6个细胞。这些水槽将是当地的最低标准,如果我不满意,请纠正我wrong@ChirayuThakur是的,这是有道理的。您必须选择具有最高对比度的局部极小值,而不一定是最低值。但某种形式的局部对比度增强可能会使这更容易。您还可以增加水平线SE上的长度,以改善想要的最小值和不想要的最小值之间的差异。
x = dip.Mean(out, process=[1, 0]).Squeeze()
y = dip.Mean(out, process=[0, 1]).Squeeze()
import matplotlib.pyplot as pp
pp.subplot(2,1,1)
pp.plot(x)
pp.subplot(2,1,2)
pp.plot(y)
pp.show()