How can I count number of stomata in the microscopic image of leaf using Python and Opencv?

Viewed 196

I want to count the number of stomata in the microscopic images of leaves. One of the samples is attached below. The stomata is characterized by oval shape in general with thick black lining in between. Since I have many images, I want to automate the process. I am familiar with Python but quite novice to computer vision.

enter image description here

With some code, I was able to count the number of cars in an image. However, it did not work with the image of the leaf for me. The sample code is given below:

import cv2
import numpy as np
import matplotlib.pyplot as plt
import cvlib as cv
from cvlib.object_detection import draw_bbox
from numpy.lib.polynomial import poly

image = cv2.imread("leaf1.jpg")
box, label, count = cv.detect_common_objects(image)
output = draw_bbox(image, box, label, count)
plt.imshow(output)
plt.show()

I got the results as follows with no detection of any object in the image. Is it possible to count the number of stomata in the leaf images as these? enter image description here

1 Answers

I hope I understood what you mean by the word stomata :)

import sys
import cv2
import numpy as np

# Load image
pth = sys.path[0]
im = cv2.imread(pth+'/stomata.jpg')
im = cv2.resize(im, (im.shape[1]//2, im.shape[0]//2))
h, w = im.shape[:2]

# Remove noise and make grayscale
blr = cv2.medianBlur(im, 11)
blr = cv2.cvtColor(blr, cv2.COLOR_BGR2GRAY)

# Remove noise again
bw = cv2.medianBlur(blr, 45)  # 51
bw = cv2.erode(bw, np.ones((5, 5), np.uint8))

# Create mask
bw = cv2.threshold(bw, 110, 255, cv2.THRESH_BINARY)[1]

# Draw white border around mask to detect stomatas near borders
cv2.rectangle(bw, (0, 0), (w, h), 255, 5)

# Find contours and sort them by position
cnts, _ = cv2.findContours(bw, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnts.sort(key=lambda x: cv2.boundingRect(x)[0])

# Find and draw blocks
for cnt in cnts:
    x, y, w, h = cv2.boundingRect(cnt)
    cv2.rectangle(im, (x, y), (x+w, y+h), (0, 255, 0), 5)
    cv2.rectangle(bw, (x, y), (x+w, y+h), 127, 5)

# Save final output
bw = cv2.cvtColor(bw, cv2.COLOR_GRAY2BGR)
cv2.imwrite(pth+'/stack.jpg', np.hstack((im, bw)))

This is a start; It is not complete and has an error in detection. You may need more images to get better results. You need to take the time to get the desired result. I'm not sure about the next sentence, but you may need to use something like CNN(ConvNet) later.

enter image description here

Related