1

My goal is detecting all the purple pollen in the image below and put the letter "P" in it. enter image description here

But the result shows that it always mistakes a black area.

enter image description here

Changing the radius in circle detection would not help because I still have lots of similar images to go. So what should I do to better it?

Here is my code:

# coding: utf-8


import cv2
import numpy as np


path = "./sample.JPG"
font = cv2.FONT_HERSHEY_COMPLEX

def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
    # initialize the dimensions of the image to be resized and
    # grab the image size
    dim = None
    (h, w) = image.shape[:2]

    # if both the width and height are None, then return the
    # original image
    if width is None and height is None:
        return image

    # check to see if the width is None
    if width is None:
        # calculate the ratio of the height and construct the
        # dimensions
        r = height / float(h)
        dim = (int(w * r), height)

    # otherwise, the height is None
    else:
        # calculate the ratio of the width and construct the
        # dimensions
        r = width / float(w)
        dim = (width, int(h * r))

    # resize the image
    resized = cv2.resize(image, dim, interpolation = inter)

    # return the resized image
    return resized

iml = cv2.imread(path,cv2.IMREAD_COLOR)
img = image_resize(iml,width=960)

cimg = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#cv2.GaussianBlur(cimg, (9,9),3)
cimg = cv2.medianBlur(cimg,5)

circles = cv2.HoughCircles(cimg[:,:,0],cv2.HOUGH_GRADIENT,1,cimg.shape[0]/16,param1=15,param2=20,minRadius=18,maxRadius=38)
circles = np.uint16(np.around(circles))[0,:]

for i in circles:
     cv2.putText(img,'P',(i[0],i[1]), font, 0.5,(0,255,0),1,cv2.LINE_AA)

cv2.imwrite("./output.jpg",img)

In addition, I also tried using color detection since all I want to detect have the same color (purple). I follow the instructions here but it still didn't work.

Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
Nghĩa Lê
  • 53
  • 3

1 Answers1

3

I think you can detect the purple directly in HSV color space if you can carefully choose the right hsv range. This colormap is taken from my other answers.

enter image description here

I select Hue(120,160), Saturation(180, 255), Value(50, 255) for this task to get the mask.

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (120, 180, 50), (160, 255, 255))

Then you can do the processing on the mask.

enter image description here

Links maybe helpful:

  1. How to define a threshold value to detect only green colour objects in an image :Opencv

  2. Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)

  3. RGB range for color red

Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • These values are better for purple: H(126,145), S(142, 255), V(57, 255). Try using this script to easily find HSV ranges: https://github.com/smeschke/juggling/blob/master/hsv_color_picker.py – Stephen Meschke Oct 01 '18 at 17:11
  • HSV is a bit difficult to use because the hue wraps at red. If you don't get good results with HSV I'd suggest trying YUV or LAB and creating a bounding box for the purple shade you want in the UV (or AB) planes. – Chungzuwalla Oct 02 '18 at 01:20
  • Thank you. Could you give me the full code? I don't know why but I couldn't do circle detection for the mask, cause my last purpose is to write the letter P into the pollen. – Nghĩa Lê Oct 04 '18 at 09:32
  • Hey my code worked now but I still don't understand the way to find the range of purple (I don't get the pic you attached). Could you explain more? – Nghĩa Lê Oct 04 '18 at 10:27