Обнаружение яблока с помощью порога - PullRequest
1 голос
/ 12 октября 2019

Я хочу обнаружить яблоки по порогу. Для этого я преобразовал изображение в HSV и рассчитал нижний и верхний пределы для функции InRange(). Получение бинарной маски из этого. Поскольку яблоки будут касаться друг друга, я использую алгоритм водораздела для их разделения.

Исходное изображение выглядит следующим образом:

in

После операции InRange() и эрозии серое изображение выглядит следующим образом:

gray

При применении алгоритма водораздела выходные данные выглядят следующим образом:

out

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

Вот мой код,

import cv2
import numpy as np
import imutils
from scipy import ndimage
from skimage.feature import peak_local_max
from skimage.morphology import watershed

img = cv2.imread('4.jpg')
img = imutils.resize(img, width=640)
# img = cv2.pyrMeanShiftFiltering(img, 21, 51)
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

lower_1 = np.array([0,50,20])
upper_1 = np.array([80,255,255])
mask1 = cv2.inRange(hsv, lower_1, upper_1)

lower_2 = np.array([160,50,20])
upper_2 = np.array([179,255,255])
mask2 = cv2.inRange(hsv, lower_2, upper_2)

gray = mask1+mask2
kernel = np.ones((7,7),np.uint8)
gray = cv2.erode(gray,kernel,iterations = 1)
# gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)

thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]


D = ndimage.distance_transform_edt(thresh)
localMax = peak_local_max(D, indices=False, min_distance=20,
    labels=thresh)

markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
labels = watershed(-D, markers, mask=thresh)
print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))

for label in np.unique(labels):
    if label == 0:
        continue

    mask = np.zeros(gray.shape, dtype="uint8")
    mask[labels == label] = 255

    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
        cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    c = max(cnts, key=cv2.contourArea)

    ((x, y), r) = cv2.minEnclosingCircle(c)
    if r > 25 and r < 55:
        cv2.circle(img, (int(x), int(y)), int(r), (0, 255, 0), 2)
        cv2.putText(img, "{}".format(round(r)), (int(x) - 10, int(y)),
            cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

cv2.imshow('thresh', thresh)
cv2.imshow('gray', gray)
cv2.imshow('img', img)

cv2.waitKey(0)
cv2.destroyAllWindows()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...