1 回答
TA贡献1856条经验 获得超5个赞
找到并画出答题卡中的所有轮廓。
申请
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
= 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)
添加回答
举报