Search code examples
pythonopencvimage-processingcomputer-visionobject-detection

Detecting the onion co-ordinates in an onion field


Due to lack of data, I have been asked to implement a non-data driven approach to find the co-ordinates of the onions in the onion field. The image would be an elevated front view.

Here is the image of an Onion Field:

image

I have tried the following:

img = cv2.imread("/content/Onion1.jpeg",0)
img_blur = cv2.blur(img,(5,5))
edges = cv2.Canny(img_blur,150,200)

The final output obtained:

Output

What are the ways through which I can do better to achieve the objective i.e. to find out the co-ordinates of the onions in the image? Can we somehow take the advantage that onions are planted in rows or some other obvious fact that I am clearly missing? Any help/advice is highly appreciated. Also, note that I am very new to OpenCV.

Edit : I have been able to isolate the green but am struggling to perform multiple template matching in order to find the peaks or peak co-ordinates.

Here is the output I got by separating the hue corresponding to green: Output
Code:

import cv2
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from google.colab.patches import cv2_imshow
## Read
img = cv2.imread("/content/Onion1.jpeg")
img = cv2.blur(img, (10,10))
cv2_imshow(img)


## convert to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

## mask of green (36,25,25) ~ (86, 255,255)
# mask = cv2.inRange(hsv, (36, 25, 25), (86, 255,255))
mask = cv2.inRange(hsv, (36, 25, 25), (86, 255,255))

## slice the green
imask = mask>0
green = np.zeros_like(img, np.uint8)
green[imask] = img[imask]

## show
cv2_imshow(green)

img_gray = cv2.cvtColor(green, cv2.COLOR_BGR2GRAY)
template = cv2.imread('/tp.png',0) # tp is just a screenshot taken of one of the peaks
w, h = template.shape[::-1]
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(green, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

cv2_imshow(green)

How can I generalise this peak detection so that it is a bit more robust?


Solution

  • I have the feeling that detecting the green color can be a good starting point.

    In the picture below, the Hue component has been used and clearly shows the distinction between the vegetation and the soil. The next step would be to find the peaks, which can be robustly achieved by grayscale correlation. (We used the second peak as the template and found the other three; the figures are matching scores.)

    enter image description here]1

    enter image description here

    Now the onions could be more precisely located by some local search near the tip of the peaks.