我正在尝试计算此图像中的丢弃数量以及这些丢弃所覆盖区域的覆盖率。 我试图将这个图像转换为黑白图像,但这些图像的中心颜色看起来与背景太相似了。所以我只得到第二张图片。 有没有办法解决这个问题或任何更好的想法? 非常感谢。
答案 0 :(得分:7)
您可以使用scipy.ndimage.binary_fill_holes
填充二进制图像的孔。我还建议使用自动阈值处理方法,例如Otsu(scikit-image
中的可用)。
from skimage import io, filters
from scipy import ndimage
import matplotlib.pyplot as plt
im = io.imread('ba3g0.jpg', as_grey=True)
val = filters.threshold_otsu(im)
drops = ndimage.binary_fill_holes(im < val)
plt.imshow(drops, cmap='gray')
plt.show()
对于丢弃的数量,您可以使用scikit-image
from skimage import measure
labels = measure.label(drops)
print(labels.max())
覆盖范围
print('coverage is %f' %(drops.mean()))
答案 1 :(得分:6)
我使用以下代码使用openCV和python检测图像中的轮廓数。
img = cv2.imread('ba3g0.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,1)
contours,h = cv2.findContours(thresh,1,2)
for cnt in contours:
cv2.drawContours(img,[cnt],0,(0,0,255),1)
答案 2 :(得分:2)
这个想法是将背景分离成看起来像背景的水滴内部。 因此,我发现背景的连通分量和内部的水滴采用了最大的连通分量,并将其值更改为前景值,这使得我在内部的图像下降为与背景不同的值。 比我使用此图像填写原始阈值图像。 最后使用填充图像我计算了相关值
import cv2
import numpy as np
from matplotlib import pyplot as plt
# Read image
I = cv2.imread('drops.jpg',0);
# Threshold
IThresh = (I>=118).astype(np.uint8)*255
# Remove from the image the biggest conneced componnet
# Find the area of each connected component
connectedComponentProps = cv2.connectedComponentsWithStats(IThresh, 8, cv2.CV_32S)
IThreshOnlyInsideDrops = np.zeros_like(connectedComponentProps[1])
IThreshOnlyInsideDrops = connectedComponentProps[1]
stat = connectedComponentProps[2]
maxArea = 0
for label in range(connectedComponentProps[0]):
cc = stat[label,:]
if cc[cv2.CC_STAT_AREA] > maxArea:
maxArea = cc[cv2.CC_STAT_AREA]
maxIndex = label
# Convert the background value to the foreground value
for label in range(connectedComponentProps[0]):
cc = stat[label,:]
if cc[cv2.CC_STAT_AREA] == maxArea:
IThreshOnlyInsideDrops[IThreshOnlyInsideDrops==label] = 0
else:
IThreshOnlyInsideDrops[IThreshOnlyInsideDrops == label] = 255
# Fill in all the IThreshOnlyInsideDrops as 0 in original IThresh
IThreshFill = IThresh
IThreshFill[IThreshOnlyInsideDrops==255] = 0
IThreshFill = np.logical_not(IThreshFill/255).astype(np.uint8)*255
plt.imshow(IThreshFill)
# Get numberof drops and cover precntage
connectedComponentPropsFinal = cv2.connectedComponentsWithStats(IThreshFill, 8, cv2.CV_32S)
NumberOfDrops = connectedComponentPropsFinal[0]
CoverPresntage = float(np.count_nonzero(IThreshFill==0)/float(IThreshFill.size))
# Print
print "Number of drops = " + str(NumberOfDrops)
print "Cover precntage = " + str(CoverPresntage)