区分圆圈和单选按钮 Opencv python

我的任务是检测图像中的圆圈和单选按钮。为此,我通过使用不同的参数尝试了霍夫圆。


问题:如果图像中的圆圈与单选按钮的半径相同,则两者都会被检测到,但在我们的情况下,它应该只检测到一个。


有没有办法区分圆圈和单选按钮(当未选中它们时)。现在我用半径限制它们,有两种不同的功能,一种用于圆形,一种用于单选按钮。上面的代码是针对圆的


    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:

https://img4.mukewang.com/651283750001a5c005050576.jpg

图片2:

https://img.mukewang.com/65128380000186a705010572.jpg

对于 Image1,它正确检测到圆圈,当它传递到单选按钮功能时,它还会为其内部绘制半径减小的圆圈(Image2),这些圆圈也被检测为单选按钮

Image3 Image3 中,它必须检测圆形和单选按钮,而我的代码只能检测圆形。

我也尝试过使用绘制轮廓,但当图像也有复选框时会出现问题。

有没有其他方法或者更好的检测方法?


一只斗牛犬
浏览 89回答 1
1回答

RISEBY

找到并画出答题卡中的所有轮廓。申请HoughCircles步骤#1:我们可以从找到给定答卷中的所有轮廓开始。contourIdx=-1意思是画出所有的轮廓。import cv2import numpy as npimage = cv2.imread('zip_grade_form.png')# Converting the image Gray scalegray = 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 cv2import numpy as npimage = cv2.imread('zip_grade_form.png')# Converting the image Gray scalegray = 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= 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 cv2from imutils import grab_contours as grb_cnsfrom imutils import resize as rszimage = cv2.imread('K1Z94.png')# Converting the image Gray scalegray = 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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python