This is a perfect sample image that includes range of black objects. 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)

But the results is disappointing as this showing contours of the above image's black objects

其中包括118条等高线.请注意,我需要找到并获取14个对象.

推荐答案

我们可以用dilate代替GaussianBlur,用RETR_EXTERNAL代替RETR_TREE,只保留大的轮廓.

  • threshold倒过来:

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

Output mask:
enter image description here

Python-3.x相关问答推荐

Gekko优化超出了方程式的界限(由于某种原因,会产生变量)

我的SELECT函数搜索的是列,而不是列中的数据.我怎么才能让它搜索数据呢?

比较和排序 DataFrame 两列中的值并在 python 中的同一行中排序

Python中根据分组/ID对两个数据框进行映射,以更接近值的升序排列

如何将搜索结果中的所有值保存在另一个列表中?

如果网站加载时间过长,如何强制 Selenium 刷新

在python中将字符串写入文本文件

使用 pandas 进行多类分类的总体准确度

python tkInter 浏览文件夹按钮

Python - For 循环数百万行

如何从另一个目录导入 python 包?

在数据类中创建类变量的正确方法

cv2 python 没有 imread 成员

如何模拟 open(...).write() 而不会出现没有这样的文件或目录错误?

python中的订单字典索引

try 在 Mac OS 中运行此命令pipenv install requests时出错

如何为 anaconda python3 安装 gi 模块?

为什么某些代码在 Python2 中是确定性的,而在 Python 3 中是非确定性的?

有效地判断一个元素是否在列表中至少出现 n 次

如何在 Python 3.4 中使用 pip 3?