Считая больше элементов, тогда это должно быть - PullRequest
1 голос
/ 22 октября 2019

Я изучаю OpenCV с помощью Python и хочу научиться считать объекты / элементы в изображении.

Я написал код для подсчета, но получаю неправильные результаты. На изображении 12 элементов, и я получаю 40, но некоторые элементы не учитываются.

Я не знаю, что я делаю неправильно.

Это код, который у меня есть:

import cv2

img = cv2.imread('slika.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

print('There are 12 elements on this image')

#cv2.imshow('img', gray)
#cv2.waitKey(0)

ret,thresh = cv2.threshold(gray,127,255,1)
contours,h = cv2.findContours(thresh,1,1)

print('Number of elements found:', len(contours))

for cnt in contours:
    cv2.drawContours(img,[cnt],0,(0,0,255),2)

cv2.imshow('img', img)
cv2.waitKey(0)

Это изображение по умолчанию с 12 элементами:

enter image description here

Это результат:

enter image description here

Вы видите, что розовый и два желтых элемента не распознаются, но это проблема с зеленым.

Что я делаю не так,и как это исправить?

1 Ответ

5 голосов
/ 22 октября 2019

Есть несколько пунктов, где можно улучшить ваш текущий код.

  1. Если вы действительно посмотрите на ваше изображение gray, вы увидите, что ваш порог 127 равенслишком низко. Желтые и розовые структуры имеют значения серого выше 127, а затем опускаются вашим cv2.threshold. По той же причине зеленая структура фрагментирована. И, как правило, лучше использовать фактические значения перечисления, такие как cv2.THRESH_BINARY_INV вместо их числовых значений.

  2. Для обнаружения контура лучше использовать cv2.RETR_EXTERNAL режим поиска, поэтому вы просто учитываете большинство внешних контуров. Опять же, используйте значения enum.

С этими изменениями ваш код работает нормально:

import cv2

# Read image
img = cv2.imread('DIVmd.jpg')

# Convert image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Show grayscale image
cv2.imshow('gray', gray)

print('There are 12 elements on this image')

# Inverse binary threshold image with threshold at 224,
# i.e. every pixel with value above 224 is set to 0,
# and every pixel with value below 224 is set to 1
_, thresh = cv2.threshold(gray, 224, 255, cv2.THRESH_BINARY_INV)

# Show thresholded image
cv2.imshow('thresh', thresh)

# Find contours
#   cv2.RETR_EXTERNAL:      retrieves only the extreme outer contours
#   cv2.CHAIN_APPROX_NONE:  stores absolutely all the contour points
contours, h = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

print('Number of elements found:', len(contours))

# Iterate all found contours
for cnt in contours:

    # Draw contour in original/final image
    cv2.drawContours(img, [cnt], 0, (0, 0, 255), 2)

# Show final image
cv2.imshow('img', img)
cv2.waitKey(0)

В целях визуализации это ваше gray изображение:

Gray

Это фактическое пороговое изображение thresh:

Thresh

И, наконец, вывод img:

Output

Конечно, печатные выводы теперь тоже правильные:

There are 12 elements on this image
Number of elements found: 12

Надеюсь, это поможет!

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