1

我正在创建一个程序来自动将太阳能电池从光伏模块中分离出来,我首先使用自适应阈值对图像进行阈值处理以获得以下图像

阈值图像

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

膨胀后的阈值图像(结构元素大小(10,10)

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

膨胀后的阈值图像(结构元素大小(15,15)

我已经尝试了其他可用的结构元素,例如交叉和矩形,但没有任何成功,因此我需要定义一个自定义内核并且不知道如何定义一个。

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()

阈值处理前的原始图像

4

1 回答 1

3

我的第一条建议是不要立即设置门槛。阈值是您最终想要做的事情。阈值化会丢弃有价值的信息。形态学运算也适用于灰度图像!

选择正确的形态运算符来只保留您感兴趣的形状实际上非常直观。在这种情况下,您希望同时保留水平线和垂直线。让我们使用线结构元素。线条是深色的,所以我们使用闭合来删除看起来不像我们的线条的东西。

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

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

import PyDIP as dip
img = dip.ImageReadTIFF('/Users/cris/Downloads/ZrF7k.tif')
img = img.TensorElement(1) # keep only green channel
img = img[0:-2,1:-1]       # let's remove the artifacts at the right and top edges
f1 = dip.Closing(img, dip.SE([50,1],'rectangular'))
f2 = dip.Closing(img, dip.SE([1,50],'rectangular'))
out = dip.Infimum(f1, f2)
out.Show('lin')

在此处输入图像描述

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

我在这里利用了这样一个事实,即面板对图像非常直,并且覆盖了整个图像。我们可以简单地沿行和列进行平均投影:

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()

在此处输入图像描述

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

于 2018-03-10T06:35:58.677 回答