[英]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:
圖 2:
對於 Image1,它正確檢測圓,當它傳遞給單選按鈕功能時,它還為它的內部繪制圓(Image2),半徑減小,這些圓也被檢測為單選按鈕
在Image3 Image3 中,它必須檢測圓形和單選按鈕,而我的代碼只能檢測圓形。
我也嘗試過使用繪制輪廓,但是當圖像也有復選框時會出現問題。
有沒有其他方法或更好的檢測方法?
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)。 來源
我們可以使用p
和a
值來分隔每個對象,因為每個對象都有一個唯一的p
和a
值。
例如,在圖像 3 中,
p
= 73 和a
= 4p
= 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.