gpt4 book ai didi

python-3.x - 如何在 cv2.findcontours 上获得准确的结果以在 BW/黑白图像中查找对象?

转载 作者:行者123 更新时间:2023-12-05 01:52:41 25 4
gpt4 key购买 nike

这是一个完美的样本图像,包括一系列黑色物体。 silhouette black plants in white background

这段代码假设找到所有黑色植物

import cv2 as cv
import numpy as np
img = cv.imread("12.jpg")
tresh_min= 200
tresh_max=255
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blurred = cv.GaussianBlur(gray, (5, 5), 0)
_, threshold = cv.threshold(blurred, tresh_min, tresh_max, 0)
(contours, _)= cv.findContours(threshold, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

print(f'Number of countours: {len(contours)}')
mask = np.ones(img.shape[:2], dtype="uint8") * 255


# Draw the contours on the mask
cv.drawContours(mask, contours=contours, contourIdx=-1, color=(0, 255, 255), thickness=2)

但结果却令人失望 showing contours of the above image's black objects

这包括 118 个轮廓。请注意,我需要找到并取走 14 个对象。当轮廓实际上不正确时如何切割每株植物。或者至少将非常接近的那些加入到每个更大的轮廓中,以分别保存对象?谢谢

最佳答案

我们可以使用dilate而不是GaussianBlur,使用RETR_EXTERNAL而不是RETR_TREE,并且只保留大的轮廓。

  • 反转阈值:

     _, threshold = cv.threshold(gray, tresh_min, tresh_max, cv.THRESH_BINARY_INV)
  • 用柱核膨胀(假设植物又高又窄):

     dilate_threshold = cv.dilate(threshold, np.ones((15, 1), np.uint8))
  • 遍历等高线列表,只保留面积大于 1000 的那些。


代码示例:

import cv2 as cv
import numpy as np

img = cv.imread("12.jpg")
tresh_min= 200
tresh_max=255
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
#blurred = cv.GaussianBlur(gray, (5, 5), 0)
_, threshold = cv.threshold(gray, tresh_min, tresh_max, cv.THRESH_BINARY_INV)
dilate_threshold = cv.dilate(threshold, np.ones((15, 1), np.uint8))
(contours, _)= cv.findContours(dilate_threshold, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) # Use RETR_EXTERNAL instead of RETR_TREE

print(f'Number of countours: {len(contours)}')
mask = np.ones(img.shape[:2], dtype="uint8") * 255


# Draw the contours on the mask
large_contours = []
for c in contours:
area_tresh = 1000
area = cv.contourArea(c)
if area > area_tresh:
cv.drawContours(mask, [c], contourIdx=-1, color=(0, 255, 255), thickness=1)
large_contours.append(c) # Append to list of "large contours".

print(f'Number of large countours: {len(large_contours)}')

# Show output for testing
cv.imshow('threshold', threshold)
cv.imshow('dilate_threshold', dilate_threshold)
cv.imshow('mask', mask)
cv.waitKey()
cv.destroyAllWindows()

输出掩码:
enter image description here

关于python-3.x - 如何在 cv2.findcontours 上获得准确的结果以在 BW/黑白图像中查找对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71524593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com