I tried to count the leaves of this image by taking the code of this post:
Some things were changed, like cleaning the image with morphological operations
I want to separate the shapes that look like two united circles with a line, since I believe the algorithm would work better. Besides, I have a doubt regarding the final result, because the lines are not closed. How can I improve the code or the image for the final result and have the lines closed like the ones in the first image?
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import label
import urllib.request
# https://stackoverflow.com/a/14617359/7690982
def function(a, img, img_gray):
# Added several elliptical structuring element for better morphology process
struct_big = cv.getStructuringElement(cv.MORPH_ELLIPSE,(4,4))
struct_small = cv.getStructuringElement(cv.MORPH_ELLIPSE,(3,3))
# increase border size
border = cv.dilate(img, struct_big, iterations=1)
border = border - cv.erode(img, struct_small)
dt = cv.distanceTransform(img, cv.DIST_L2, 3)
dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(np.uint8)
# blur the signal lighty to remove noise
dt = cv.GaussianBlur(dt,(7,7),-1)
# Adaptive threshold to extract local maxima of distance trasnform signal
#PARA LA PRIMERA IMAGEN 11 -5
#35 45 o 50 -5
#13, -5
dt = cv.adaptiveThreshold(dt, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, -5)
# Morphology operation to clean the thresholded signal
dt = cv.erode(dt,struct_small,iterations = 1)
dt = cv.dilate(dt,struct_big,iterations = 4)
# Labeling
lbl, ncc = label(dt)
lbl = lbl * (255 / (ncc + 1))
print(lbl)
# Completing the markers now.
lbl[border >= 80] = 255
lbl = lbl.astype(np.int32)
cv.watershed(a, lbl)
print("[INFO] {} unique segments found".format(len(np.unique(lbl)) - 1))
lbl[lbl == -1] = 0
lbl = lbl.astype(np.uint8)
return 255 - lbl
if __name__ == '__main__':
img = cv.imread('/home/rainor/Escritorio/VA/Practica2/PSI_Tray031_2015-12-27--09-03-57_top.png')
# img = cv.imread('/home/rainor/Escritorio/VA/Practica2/PSI_Tray032_2016-01-14--14-06-50_top.png')
# Open Image
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
img = cv.filter2D(img, -1, kernel)
plt.imshow(img)
plt.show()
# proper color segmentation
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
mask = cv.inRange(hsv, (25, 25, 25), (70, 255, 255))
mask = cv.medianBlur(mask, 9)
kernel = np.ones((12,12),np.uint8)
mask = cv.morphologyEx(mask, cv.MORPH_OPEN, kernel)
print("Esta es la que quitamos el ruido")
plt.imshow(mask, cmap='gray')
plt.show()
imask = mask > 0
slicer = np.zeros_like(img, np.uint8)
slicer[imask] = img[imask]
# Image Binarization
img_gray = cv.cvtColor(slicer, cv.COLOR_BGR2GRAY)
print("Blanco y negro: check")
plt.imshow(img_gray, cmap = 'gray')
plt.show()
_, img_bin = cv.threshold(img_gray, 0, 100, cv.THRESH_BINARY)
print("Imagen plantas Amarillas fondo morado (tiene suciedda igual quitando como dije en BN el ruido)")
plt.imshow(img_bin, cmap='gray')
plt.show()
# Morphological Gradient
cv.morphologyEx(img_bin, cv.MORPH_OPEN,cv.getStructuringElement(cv.MORPH_ELLIPSE,(1,1)),img_bin,(-1,-1),10)
cv.morphologyEx(img_bin, cv.MORPH_ERODE,cv.getStructuringElement(cv.MORPH_ELLIPSE,(1,1)),img_bin,(-1,-1),3)
# Segmentation
result = function(img, img_bin, img_gray)
plt.imshow(np.hstack([result, img_gray]), cmap='Set3')
plt.show()
# Final Picture
result[result != 255] = 0
result = cv.dilate(result, None)
img[result == 255] = (0, 0, 255)
plt.imshow(result)
plt.show()
# function(img1)
Original images
Result of border image 1
Final result of image 1
Result of border image 2
Final result of image 1