首页 > 解决方案 > 识别和计数不同于背景的物体

问题描述

我尝试使用 python、NumPy 和 OpenCV 来分析下面的图像,并在找到的每个对象上画一个圆圈。这里的想法不是识别错误,仅识别与背景不同的任何对象。

原图: 在此处输入图像描述

这是我正在使用的代码。

import cv2
import numpy as np
img = cv2.imread('per.jpeg', cv2.IMREAD_GRAYSCALE)
if cv2.__version__.startswith('2.'):
    detector = cv2.SimpleBlobDetector()
else:
    detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(img)
print(len(keypoints))
imgKeyPoints = cv2.drawKeypoints(img, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
status = cv2.imwrite('teste.jpeg',imgKeyPoints)
print("Image written to file-system : ",status)

但问题是我得到的结果只有一个灰度图像,没有任何计数或红色圆圈,如下所示: 在此处输入图像描述

由于我是 OpenCV 和对象识别领域的新手,我无法确定问题所在,我们将不胜感激任何帮助。

标签: pythonpython-3.xnumpyopencv

解决方案


这是 Python/OpenCV 中的一种方法。

HSV 颜色空间中错误颜色的阈值。然后使用形态学来清理阈值。然后得到轮廓。然后找到每个轮廓周围的最小封闭圆。然后将半径偏大一点,并在每个虫子周围画一个圆圈。

输入:

在此处输入图像描述

import cv2
import numpy as np

# read image
img = cv2.imread('bugs.jpg')

# convert image to hsv colorspace
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# threshold on bugs color
lower=(0,90,10)
upper=(100,250,170)
thresh = cv2.inRange(hsv, lower, upper)

# apply morphology to clean up
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (6,6))
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)

# get external contours
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

result = img.copy()
bias = 10
for cntr in contours:
    center, radius = cv2.minEnclosingCircle(cntr)
    cx = int(round(center[0]))
    cy = int(round(center[1]))
    rr = int(round(radius)) + bias
    cv2.circle(result, (cx,cy), rr, (0, 0, 255), 2)

# save results
cv2.imwrite('bugs_threshold.jpg', thresh)
cv2.imwrite('bugs_cleaned.jpg', morph)
cv2.imwrite('bugs_circled.jpg', result)

# display results
cv2.imshow('thresh', thresh)
cv2.imshow('morph', morph)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

阈值图像:

在此处输入图像描述

形态清洁图像:

在此处输入图像描述

产生的圈子:

在此处输入图像描述


推荐阅读