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)