如何使用openCV将图像分成两部分而不穿过任何物体?
How to divide image into two parts without crossing any object using openCV?
我正在使用对象检测机器学习模型(只有 1 个对象)。如果图像中有几个对象,它会很好地工作。但是,如果我的图像有超过 300 个对象,它就无法识别任何东西。所以,我想把它分成两部分或四部分,不跨越任何对象。
我用了threshold otsu and get this threshold otsu image. Actually I want to divide my image by this line expect image。我认为如果对图像的每个部分都进行预测,我的模型会很好用。
我尝试使用findContour,找到大于一半图像区域的contourArea,将其绘制到新图像中,获取剩余部分并绘制到另一个图像中。但大部分轮廓区域达不到图像区域的1/10。这不是一个好的解决方案。
我想过如何检测一条线触摸两个边界(顶部和底部),我该怎么做?
如有任何建议,我们将不胜感激。非常感谢。
由于您的兴趣区域已经分离,您可以使用 connectedComponents 来获取这些区域的边界框。我的做法如下。
img = cv2.imread('circles.png',0)
img = img[20:,20:] # remove the connecting lines on the top and the left sides
_, img = cv2.threshold(img,0,1,cv2.THRESH_BINARY)
labels,stats= cv2.connectedComponentsWithStats(img,connectivity=8)[1:3]
plt.imshow(labels,'tab10')
plt.show()
如您所见,两个兴趣区域具有不同的标签。我们需要做的就是获取这些区域的边界框。但首先,我们必须获得区域的索引。为此,我们可以使用区域的大小,因为在背景(蓝色)之后,它们具有最大的区域。
areas = stats[1:,cv2.CC_STAT_AREA] # the first index is always for the background, we do not need that, so remove the background index
roi_indices = np.flip(np.argsort(areas))[0:2] # this will give you the indices of two largest labels in the image, which are your ROIs
# Coordinates of bounding boxes
left = stats[1:,cv2.CC_STAT_LEFT]
top = stats[1:,cv2.CC_STAT_TOP]
width = stats[1:,cv2.CC_STAT_WIDTH]
height = stats[1:,cv2.CC_STAT_HEIGHT]
for i in range(2):
roi_ind = roi_indices[i]
roi = labels==roi_ind+1
roi_top = top[roi_ind]
roi_bottom = roi_top+height[roi_ind]
roi_left = left[roi_ind]
roi_right = roi_left+width[roi_ind]
roi = roi[roi_top:roi_bottom,roi_left:roi_right]
plt.imshow(roi,'gray')
plt.show()
请注意,我的方法仅适用于 2 个区域。为了分成 4 个区域,您需要一些其他方法。
我正在使用对象检测机器学习模型(只有 1 个对象)。如果图像中有几个对象,它会很好地工作。但是,如果我的图像有超过 300 个对象,它就无法识别任何东西。所以,我想把它分成两部分或四部分,不跨越任何对象。
我用了threshold otsu and get this threshold otsu image. Actually I want to divide my image by this line expect image。我认为如果对图像的每个部分都进行预测,我的模型会很好用。
我尝试使用findContour,找到大于一半图像区域的contourArea,将其绘制到新图像中,获取剩余部分并绘制到另一个图像中。但大部分轮廓区域达不到图像区域的1/10。这不是一个好的解决方案。
我想过如何检测一条线触摸两个边界(顶部和底部),我该怎么做?
如有任何建议,我们将不胜感激。非常感谢。
由于您的兴趣区域已经分离,您可以使用 connectedComponents 来获取这些区域的边界框。我的做法如下。
img = cv2.imread('circles.png',0)
img = img[20:,20:] # remove the connecting lines on the top and the left sides
_, img = cv2.threshold(img,0,1,cv2.THRESH_BINARY)
labels,stats= cv2.connectedComponentsWithStats(img,connectivity=8)[1:3]
plt.imshow(labels,'tab10')
plt.show()
如您所见,两个兴趣区域具有不同的标签。我们需要做的就是获取这些区域的边界框。但首先,我们必须获得区域的索引。为此,我们可以使用区域的大小,因为在背景(蓝色)之后,它们具有最大的区域。
areas = stats[1:,cv2.CC_STAT_AREA] # the first index is always for the background, we do not need that, so remove the background index
roi_indices = np.flip(np.argsort(areas))[0:2] # this will give you the indices of two largest labels in the image, which are your ROIs
# Coordinates of bounding boxes
left = stats[1:,cv2.CC_STAT_LEFT]
top = stats[1:,cv2.CC_STAT_TOP]
width = stats[1:,cv2.CC_STAT_WIDTH]
height = stats[1:,cv2.CC_STAT_HEIGHT]
for i in range(2):
roi_ind = roi_indices[i]
roi = labels==roi_ind+1
roi_top = top[roi_ind]
roi_bottom = roi_top+height[roi_ind]
roi_left = left[roi_ind]
roi_right = roi_left+width[roi_ind]
roi = roi[roi_top:roi_bottom,roi_left:roi_right]
plt.imshow(roi,'gray')
plt.show()
请注意,我的方法仅适用于 2 个区域。为了分成 4 个区域,您需要一些其他方法。