Подсчет специальных элементов на изображении с помощью OpenCV и Python - PullRequest
2 голосов
/ 22 октября 2019

Я хочу посчитать количество деревьев на этой картинке сверху.

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

enter image description here

Я преобразовал изображение в серый, а затем установил порог * (пороговое значениеделается вручную, есть ли способ найти его автоматически?), моя следующая идея - найти «центры» черных точек или «сгруппировать» их.

Я также пытался изменить яркость иконтраст, но это не сработало.

Что мне делать? Это код, который я написал:

import cv2
import numpy as np

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

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

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

#BIG PROBLEM: IM FINDING VALUE OF `40` IN THE LINE BELOW MANUALLY

# Inverse binary threshold image with threshold at 40,
_, threshold_one = cv2.threshold(gray, 40 , 255, cv2.THRESH_BINARY_INV)

# Show thresholded image
cv2.imshow('threshold image', threshold_one)
cv2.waitKey(0)

# Find contours
contours, h = cv2.findContours(threshold_one, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

print('Number of trees found:', len(contours))  #GIVES WRONG RESULT

# Iterate all found contours
for cnt in contours:

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

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

Это изображение с порогом, я пытался размыть его (чтобы соединить черные точки), но конечный результат такой же:

enter image description here

Это изображение результата:

enter image description here

1 Ответ

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

Вот грубый метод оценки количества деревьев. Идея моделировать каждое дерево как блоб, а затем использовать контурную фильтрацию с минимальной пороговой площадью, чтобы игнорировать шум. Чтобы определить автоматические пороговые уровни, вы можете использовать Порог Оцу , добавив cv2.THRESH_OTSU или Адаптивный порог с cv2.adaptiveThreshold(). Этот подход имеет проблемы, когда деревья очень близко друг к другу, так как они образуют единый шарик. Возможные улучшения могут заключаться в том, чтобы найти среднюю площадь каждого дерева, а затем найти пол с большой каплей. Вам, вероятно, потребуется обучить классификатор и использовать глубокое / машинное обучение для большей точности

enter image description here

Деревья: 102

import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
opening = cv2.morphologyEx(close, cv2.MORPH_OPEN, kernel, iterations=2)

cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
trees = 0
for c in cnts:
    area = cv2.contourArea(c)
    if area > 50:
        x,y,w,h = cv2.boundingRect(c)
        cv2.drawContours(image, [c], -1, (36,255,12), 2)
        trees += 1

print('Trees:', trees)
cv2.imshow('image', image)
cv2.waitKey()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...