簡體   English   中英

區分圓形和單選按鈕 Opencv python

[英]Differentiate between Circles and Radio buttons Opencv python

我有一個任務來檢測圖像中的圓圈和單選按鈕。 為此,我通過使用不同的參數嘗試了 Hough 圓。

問題:如果圖像中的圓與單選按鈕的半徑相同,則兩者都會被檢測到,但在我們的例子中,它應該只檢測到一個。

有沒有辦法區分圓圈和單選按鈕(當它們未被選中時)。 現在我通過 Radius 限制它們有 2 種不同的功能,一種用於圓形,一種用於單選按鈕。 上面的代碼是針對圓圈的

    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)

我對單選按鈕使用了類似的方法,但參數不同,如下所示。

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

原圖

圖 1:

圖片1

圖 2:

圖片2

對於 Image1,它正確檢測圓,當它傳遞給單選按鈕功能時,它還為它的內部繪制圓(Image2),半徑減小,這些圓也被檢測為單選按鈕

Image3 Image3 中,它必須檢測圓形和單選按鈕,而我的代碼只能檢測圓形。

我也嘗試過使用繪制輪廓,但是當圖像也有復選框時會出現問題。

有沒有其他方法或更好的檢測方法?

  1. 找出並畫出答卷中的所有輪廓。

  1. 應用HoughCircles

第 1 步:我們可以從在給定的答卷中找到所有輪廓開始。

  • contourIdx=-1表示繪制所有輪廓。

  •  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)

    結果:

  • 在此處輸入圖片說明

  • 從上面我們可以看到,除圓圈外的所有特征都被刪除了。 我們使用findContours方法刪除不需要的工件。

步驟#2:應用HoughCircles 您在問題上編寫的相同代碼。 結果:

  • 在此處輸入圖片說明

代碼:

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)

更新

  • 為了檢測復選框和單選按鈕,您需要計算contour-perimeter (p) 和contour-approximation (a)。 來源

  • 我們可以使用pa值來分隔每個對象,因為每個對象都有一個唯一的pa值。

  • 例如,在圖像 3 中,

    • 復選框: p = 73 和a = 4
    • 單選按鈕: p = 64 和a = 8。
  • 您可以找到觀察代碼的值。

  • 再次應用第一步。

    • 結果:

    • 在此處輸入圖片說明

  • 現在找到上圖中的輪廓:

    •  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)
    • 結果:

      • 在此處輸入圖片說明
    • 代碼:

       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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM