Я новичок в обработке изображений и Python. Возможно, вы видели мои любительские коды на этом сайте в последние пару дней.
Я пытаюсь подсчитать количество деревьев, используя аэрофотоснимки. Это мой код:
from PIL import Image
import cv2
import numpy as np
from skimage import io, filters, measure
from scipy import ndimage
img = Image.open("D:\\Texture analysis\\K-2.jpg")
row, col = img.size
hsvimg = img.convert('HSV')
hsvimg.mode = 'RGB'
hsvimg.save('newImage2.jpg')
npHSI = np.asarray(hsvimg) #Convert HSI Image to np image
blur = cv2.GaussianBlur(npHSI, (45, 45), 5)
assert isinstance(blur, np.ndarray) ##############################
assert len(blur.shape) == 3 #Convert np Image to HSI Image
assert blur.shape[2] == 3 ##############################
hsiBlur = Image.fromarray(blur, 'RGB')
hsiBlur.save('hsiBlur.jpg') #Save the blurred image
## Read
img = cv2.imread("D:\\Texture analysis\\hsiBlur.jpg")
## convert to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#Threshold the image and segment the trees
mask = cv2.inRange(hsv, (36, 25, 25), (70, 255,255))
imask = mask>0
green = np.zeros_like(img, np.uint8)
green[imask] = img[imask]
## save
cv2.imwrite("green.png", green)
#Count the number of trees
im = io.imread('green.png', as_grey=True)
val = filters.threshold_otsu(im)
drops = ndimage.binary_fill_holes(im < val)
labels = measure.label(drops)
print(labels.max())
Исходное изображение:
HSI изображение с гауссовым фильтром:
Сегментированное изображение:
Последняя часть кода возвращает 7
, что является неправильным выводом. Значение должно быть выше 50. Как правильно подсчитать количество зеленых сегментов в конечном сегментированном изображении?
EDIT
Я преобразовал green.png
в двоичную и применил эрозию с 3x3 filter
и iterated it 7 times
для удаления шума.
Это то, что я сделал в конце. Я перешел по этой ссылке stackoverflow
##save
cv2.imwrite("green.png", green)
#Convert to grayscale
gray = np.dot(green[...,:3], [0.299, 0.587, 0.114])
cv2.imwrite("grayScale.jpg", gray)
#Binarize the grayscale image
ret,bin_img = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
cv2.imwrite("bin_img.jpg", bin_img)
#Erosion to remove the noise
kernel = np.ones((3, 3),np.uint8)
erosion = cv2.erode(gray, kernel, iterations = 7)
cv2.imwrite("erosion.jpg", erosion)
#Count the number of trees
finalImage = cv2.imread('erosion.jpg')
finalImage = cv2.cvtColor(finalImage, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(finalImage, 127, 255, 1)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cv2.drawContours(finalImage,[cnt],0,(0,0,255),1)
Саурав , упомянутый в его ответе ... размер "контуров" даст вам счет . Это print(contour.size())
дает ошибку, а print(contour)
просто печатает длинный двумерный массив. Как я могу получить размер контура?
PS. Я не загружал изображения в градациях серого, бинарные и эродированные изображения, потому что чувствовал, что изображения уже занимают слишком много места, и я могу загрузить их, если кто-нибудь захочет.