如何使用OpenCV检测/查找Checkbox轮廓

问题描述 投票:4回答:2

我有几个图像,我需要通过使用计算机视觉检测复选框来做OMR。

我正在使用findContours仅在扫描文档中的复选框上绘制轮廓。但算法会提取文本的每个轮廓。

from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import argparse, imutils, cv2, matplotlib
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

image = cv2.imread("1.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 75, 200)

im_test = [blurred, cv2.GaussianBlur(gray, (7, 7), 0), cv2.GaussianBlur(gray, (5, 5), 5), cv2.GaussianBlur(gray, (11, 11), 0)]
im_thresh = [ cv2.threshold(i, 127, 255, 0)  for i in im_test ]
im_thresh_0 = [i[1] for i in im_thresh ]
im_cnt = [cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[0] for thresh in im_thresh_0]

im_drawn = [cv2.drawContours(image.copy(), contours, -1, (0,255,0), 1) for contours in im_cnt]

plt.imshow(im_drawn[0])
plt.show()

输入图片:enter image description here

python opencv opencv-contour object-recognition
2个回答
2
投票

由于我们只想检测复选框,因此我们的想法是使用两种过滤方法将所需的框与单词隔离开来。在预处理并找到轮廓后,我们可以迭代每个轮廓并应用滤波器。我们使用具有最小和最大阈值水平的cv2.contourArea(),然后使用cv2.approxPolyDP()计算纵横比,因为正方形的纵横比接近1。

为了检测图像中的边缘,我们可以使用cv2.Canny(),然后使用cv2.findContours()抓取轮廓,从而生成此图像。注意如何检测包括单词和复选框在内的所有轮廓。

enter image description here

接下来,我们使用阈值区域和纵横比迭代每个检测到的轮廓并进行滤波。使用此方法,检测到所有52个复选框。

enter image description here

产量

('checkbox_contours',52)

为了防止潜在的误报,我们可以添加第3个过滤器以确保每个轮廓有四个点(它更像是一个正方形)。如果输入图像来自一个角度,我们可以使用four point transform作为预处理步骤来获得图像的鸟瞰图。

另一个输入图像集

产量

('checkbox_contours',2)

import numpy as np
import imutils, cv2

original_image = cv2.imread("1.jpg")
image = original_image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 120, 255, 1)

cv2.imshow("edged", edged)

cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

checkbox_contours = []

threshold_max_area = 250
threshold_min_area = 200
contour_image = edged.copy()

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.035 * peri, True)
    (x, y, w, h) = cv2.boundingRect(approx)
    aspect_ratio = w / float(h)
    area = cv2.contourArea(c) 
    if area < threshold_max_area and area > threshold_min_area and (aspect_ratio >= 0.9 and aspect_ratio <= 1.1):
        cv2.drawContours(original_image,[c], 0, (0,255,0), 3)
        checkbox_contours.append(c)

print('checkbox_contours', len(checkbox_contours))
cv2.imshow("checkboxes", original_image)
cv2.waitKey(0)

1
投票

那么......复选框总是在图像的那个区域吗?复选框始终在图像上保持相同的大小区域?

如果是,您只能在图像的该区域运行findContours ...

或者也许是模板与多个对象匹配,例如来自OpenCV docs:https://docs.opencv.org/3.4.3/d4/dc6/tutorial_py_template_matching.html

© www.soinside.com 2019 - 2024. All rights reserved.