count colored dots in image

前端 未结 3 1225
囚心锁ツ
囚心锁ツ 2020-12-09 00:15

First of all, sorry if this topic already exists (I think this is a common task, but couldn\'t find anything).

The point, is that I have an image who shows different

3条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-09 00:45

    Here is a sample solution based on OpenCV 3.2 and Python 2.7.

    To count the colored dots, repeat below 4 steps once per color type.

    1. Apply median filter to reduce noise - cv2.medianBlur().
    2. Apply color threshold to segment the colored dots - use cv2.inRange().
    3. Use Hough Circle Transform to detect the circles - use circles = cv2.HoughCircles(mask,cv2.HOUGH_GRADIENT,...)
    4. Loop through each detected circles to draw its center and a circle around it, and count the numbers of colored dots.

    Sample images of dots detected:

    Red - 10 dots

    Green - 39 dots

    Yellow - 30 dots

    Take note that the last yellow dots at the right side with less than half a circle hasn't been detected. This is likely a limitation of the Hough Circle Transform cv2.HoughCircles(). So you need to decide how to handle this type of issue if it happens.

    Here is the sample code:

    import cv2
    import numpy
    
    red = [(0,0,240),(10,10,255)] # lower and upper 
    green = [(0,240,0),(10,255,10)]
    yellow = [(0,240,250),(10,255,255)]
    dot_colors = [red, green, yellow]
        
    img = cv2.imread('./imagesStackoverflow/count_colored_dots.jpg')   
    # apply medianBlur to smooth image before threshholding
    blur= cv2.medianBlur(img, 7) # smooth image by 7x7 pixels, may need to adjust a bit
    
    for lower, upper in dot_colors:
        output = img.copy()
        # apply threshhold color to white (255,255, 255) and the rest to black(0,0,0)
        mask = cv2.inRange(blur,lower,upper) 
    
        circles = cv2.HoughCircles(mask,cv2.HOUGH_GRADIENT,1,20,param1=20,param2=8,
                                   minRadius=0,maxRadius=60)    
        index = 0
        if circles is not None:
            # convert the (x, y) coordinates and radius of the circles to integers
            circles = numpy.round(circles[0, :]).astype("int")
    
            # loop over the (x, y) coordinates and radius of the circles
            for (x, y, r) in circles:
                # draw the circle in the output image, 
                #   then draw a rectangle corresponding to the center of the circle
                cv2.circle(output, (x, y), r, (255, 0, 255), 2)
                cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (255, 0, 255), -1)
    
                index = index + 1
                #print str(index) + " : " + str(r) + ", (x,y) = " + str(x) + ', ' + str(y)
            print 'No. of circles detected = {}'.format(index)
    

    Hope this help.

提交回复
热议问题