如何在python图片中计算段数?

时间:2019-01-09 09:17:22

标签: python-3.x image-processing

我是图像处理和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())

原始图片: K-2.jpg

具有高斯滤波器的HSI图像: hsiBlur.jpg

分段图像: green.png

代码的最后一部分返回7,这是错误的输出。该值应大于50。如何正确计算最终分割图像中绿色分割的数量?

编辑

我将green.png转换为二进制并使用3x3 filteriterated it 7 times进行腐蚀以消除噪声。 这就是我最后所做的。我遵循了这个stackoverflow link

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

Saurav 在他的回答 ...中,“轮廓”的大小将为您计数 print(contour.size())给出了一个错误,print(contour)仅打印了一个较长的2D数组。如何获得轮廓的大小?

PS。我没有上传灰度,二进制和侵蚀的图像,因为我觉得这些图像已经占用了太多空间,如果有人愿意,我仍然可以上传它们。

1 个答案:

答案 0 :(得分:1)

我找到了52个带有该脚本的树:

from PIL import Image, ImageDraw, ImageFont

image = Image.open('04uX3.jpg')
pixels = image.load()
size = image.size
draw = ImageDraw.Draw(image)
font = ImageFont.truetype('arial', 60)
i = 1
for x in range(0, size[0], 100):
    for y in range(0, size[1], 100):
        if pixels[x, y][1] > 200:
            draw.text((x, y), str(i), (255, 0, 0), font=font)
            i += 1
image.save('result.png')

您可以看到未检测到一些树,并且检测到了一些非树。因此,这是非常粗略的计算:

trees detected