简体   繁体   中英

Differentiate between Circles and Radio buttons Opencv python

I have a task to detect Circles and Radio buttons in an Image. For this I tried Hough circles by having different parameters.

Issues : If the circles in the Image are of same radius of Radio buttons both are detected, but in our case it should only detect only one.

Is there a way to differentiate between circles and Radio buttons (when they are not checked). Right now I am limiting them by Radius with 2 different functions one for circle and one for radio button. The above code is for circles

    circle_contours=[]
    # Converting the image Gray scale
    gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
    # Blur the image to reduce noise
    img_blur = cv2.medianBlur(gray, 5)
    # Apply hough transform on the image
    circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1,20, param1=50, param2=20, 
    minRadius=11, maxRadius=21)
    # Draw detected circles
    if circles is not None:
       circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
       # Draw outer circle
       cv2.circle(image1, (i[0], i[1]), i[2], (34, 255, 34), 2)
       circle_contours.append(circles)

I have used a similar approach for radio buttons but with different parameters as below.

    radio_buttons= cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1,20, param1=50, param2=16, 
    minRadius=9, maxRadius=10)

Original Image

Image 1:

图片1

Image 2:

图片2

For the Image1 it detects circles correctly and when it is passed to the radio buttons function it also draws circles(Image2) for the inner part of it with a reduced radius which are also detected as radio buttons

In Image3 Image3 it has to detect Circle and Radio buttons, where my code is only able to detect circles.

I have also tried using draw contours but it had issues when the Image also has checkboxes.

Is there any other approach or a better way for detection?

  1. Find and draw all the contours in the answer-sheet.

  1. Apply HoughCircles

Step #1: We could start with finding all contours in the given answer-sheet .

  • contourIdx=-1 means to draw all the contours.

  •  import cv2 import numpy as np image = cv2.imread('zip_grade_form.png') # Converting the image Gray scale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(src=gray, thresh=127, maxval=255, type=0) contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE) gray = cv2.drawContours(image=gray, contours=contours, contourIdx=-1, color=(255, 255, 255), thickness=2)

    Result:

  • 在此处输入图片说明

  • From above we can see that all features except circles are removed. We use the findContours method to remove unwanted artifacts.

Step#2: Apply HoughCircles . The same code you wrote on the question. Result:

  • 在此处输入图片说明

Code:

import cv2
import numpy as np

image = cv2.imread('zip_grade_form.png')

# Converting the image Gray scale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(src=gray, thresh=127, maxval=255, type=0)

contours, hierarchy = cv2.findContours(image=thresh,
                                       mode=cv2.RETR_TREE,
                                       method=cv2.CHAIN_APPROX_SIMPLE)

gray = cv2.drawContours(image=gray, contours=contours, contourIdx=-1,
                        color=(255, 255, 255), thickness=2)

cv2.imwrite("gray.png", gray)

img_blur = cv2.medianBlur(gray, 5)
circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=16,
                           minRadius=9, maxRadius=10)

circle_contours = []

if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        # Draw outer circle
        cv2.circle(image, (i[0], i[1]), i[2], (108, 105, 255), 2)
        circle_contours.append(circles)


cv2.imwrite("circles.png", image)

Update

  • For detecting check-boxes and radio-buttons you need to calculate the contour-perimeter (p) and the contour-approximation (a). source

  • We can separate each object using p and a value since each object has a unique p and a values.

  • For instance, in image-3,

    • check-box: p = 73 and a = 4
    • radio-button: p = 64 and a = 8.
  • You can find the values observing the code.

  • Apply the 1st step again.

    • Result:

    • 在此处输入图片说明

  • Now find the contours in the above image:

    •  if len(approx) == 8 and int(p) == 64: cv2.drawContours(image, [c], -1, (180, 105, 255), 3) elif len(approx) == 4 and int(p) == 73: cv2.drawContours(image, [c], -1, (180, 105, 255), 3)
    • Result:

      • 在此处输入图片说明
    • Code:

       import cv2 from imutils import grab_contours as grb_cns from imutils import resize as rsz image = cv2.imread('K1Z94.png') # Converting the image Gray scale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(src=gray, thresh=127, maxval=255, type=0) contours, hierarchy = cv2.findContours(image=thresh.copy(), mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE) gray = cv2.drawContours(image=gray, contours=contours, contourIdx=-1, color=(255, 255, 255), thickness=2) resized = rsz(gray, width=300) ratio = gray.shape[0] / float(gray.shape[0]) canny = cv2.Canny(gray, 50, 200) thresh = cv2.threshold(src=canny, thresh=60, maxval=255, type=cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1] cns = cv2.findContours(image=thresh.copy(), mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE) cns = grb_cns(cns) for c in cns: p = cv2.arcLength(c, True) # perimeter approx = cv2.approxPolyDP(c, 0.04 * p, True) M = cv2.moments(c) # check if the all values of M are 0. all_zr = all(value == 0 for value in M.values()) if not all_zr: cX = int((M["m10"] / M["m00"])) cY = int((M["m01"] / M["m00"])) c = c.astype("float") c *= ratio c = c.astype("int") # Circles: (radio-buttons) if len(approx) == 8 and int(p) == 64: cv2.drawContours(image, [c], -1, (180, 105, 255), 3) elif len(approx) == 4 and int(p) == 73: cv2.drawContours(image, [c], -1, (180, 105, 255), 3) cv2.imwrite("result.png", image)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM