Идентифицировать и считать объекты, отличные от фона

avatar
Paul Mark
8 августа 2021 в 18:19
81
1
0

Я пытаюсь использовать python, NumPy и OpenCV, чтобы проанализировать изображение ниже и просто нарисовать круг на каждом найденном объекте. Идея здесь не в том, чтобы идентифицировать ошибку, а в том, чтобы идентифицировать любой объект, который отличается от фона.

Исходное изображение: enter image description here

Вот код, который я использую.

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)

Но проблема в том, что в результате я получаю только изображение в оттенках серого без подсчета или красного круга, как показано ниже: enter image description here

Поскольку я новичок в OpenCV и мире распознавания объектов, я не могу определить, что не так, и любая помощь будет очень признательна.

Источник
Micka
8 августа 2021 в 19:33
0

С таким хорошо контролируемым фоном вы можете использовать вычитание фона (функция cv::absdiff) или осторожное обнаружение краев и должны получить отличные результаты.

Ответы (1)

avatar
fmw42
8 августа 2021 в 19:06
1

Вот один из способов в Python/OpenCV.

Порог цвета жуков в цветовом пространстве HSV. Затем используйте морфологию, чтобы очистить порог. Затем получите контуры. Затем найдите минимальную охватывающую окружность вокруг каждого контура. Затем сместите радиус, чтобы сделать его немного больше, и нарисуйте окружность вокруг каждого жука.

Ввод:

enter image description here

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

Пороговое изображение:

enter image description here

Очищенное изображение морфологии:

enter image description here

Результирующие круги:

enter image description here

Paul Mark
8 августа 2021 в 19:13
0

спасибо за ваш код и объяснение, я буду использовать его в своих исследованиях с другими дисперсиями и другими типами ошибок.