Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用OpenCV检测/查找复选框轮廓_Python_Opencv_Image Processing_Computer Vision_Opencv Contour - Fatal编程技术网

Python 如何使用OpenCV检测/查找复选框轮廓

Python 如何使用OpenCV检测/查找复选框轮廓,python,opencv,image-processing,computer-vision,opencv-contour,Python,Opencv,Image Processing,Computer Vision,Opencv Contour,我有几个图像,我需要通过使用计算机视觉检测复选框来进行OMR 我使用findContours仅在扫描文档中的复选框上绘制轮廓。但是该算法提取文本的每个轮廓 从imutils.perspective导入四点变换 从imutils导入等高线 将numpy作为np导入 导入argparse、imutils、cv2、matplotlib 将matplotlib.pyplot作为plt导入 将matplotlib.image导入为mpimg image=cv2.imread(“1.jpg”) 灰色=cv2

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

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

从imutils.perspective导入四点变换
从imutils导入等高线
将numpy作为np导入
导入argparse、imutils、cv2、matplotlib
将matplotlib.pyplot作为plt导入
将matplotlib.image导入为mpimg
image=cv2.imread(“1.jpg”)
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
模糊=cv2.高斯模糊(灰色,(5,5,0)
边缘=cv2.Canny(模糊,75200)
im_检验=[模糊,cv2.高斯模糊(灰色,(7,7,0),cv2.高斯模糊(灰色,(5,5,5),cv2.高斯模糊(灰色,(11,11,0)]
im_thresh=[cv2.im_测试中i的阈值(i,127255,0)]
im_thresh_0=[i[1]表示im_thresh中的i]
im_cnt=[cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[0]用于im_thresh_0中的thresh]
im_Drawed=[cv2.drawContours(image.copy(),轮廓,-1,(0255,0),1)用于im_cnt中的轮廓]
plt.imshow(im\u绘制[0])
plt.show()

输入图像:

很好。。。复选框是否始终位于图像的该区域?复选框始终保持图像上相同大小的区域

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


或者模板匹配多个对象,例如OpenCV文档:

因为我们只想检测复选框,所以想法是使用两种过滤方法将所需框与单词分离。在预处理和找到轮廓后,我们可以迭代每个轮廓并应用过滤器。我们使用最小和最大阈值级别,然后使用计算纵横比,因为正方形的纵横比接近1

为了检测图像中的边缘,我们可以使用 这就产生了这个图像。注意如何检测所有轮廓,包括单词和复选框

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

输出

('checkbox_contours',52)

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

另一个输入图像集

输出

(“复选框”2)

代码

将numpy导入为np
导入imutils,cv2
原始图像=cv2.imread(“1.jpg”)
image=original\u image.copy()
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
模糊=cv2.高斯模糊(灰色,(5,5,0)
边缘=cv2.Canny(模糊,120255,1)
cv2.imshow(“边缘”,边缘)
cnts=cv2.findContours(edge.copy()、cv2.RETR\u EXTERNAL、cv2.CHAIN\u APPROX\u SIMPLE)
cnts=imutils.GRAP_轮廓(cnts)
复选框_等高线=[]
阈值\最大\面积=250
阈值最小面积=200
轮廓\图像=边缘。复制()
对于碳纳米管中的碳:
peri=cv2.弧长(c,真)
近似值=cv2.近似聚合度(c,0.035*peri,真)
(x,y,w,h)=cv2.边界矩形(近似值)
纵横比=宽/浮点数(h)
面积=cv2。轮廓面积(c)

如果面积<阈值\最大值\面积和面积>阈值\最小值\面积和(纵横比>=0.9和纵横比每个文档在不同区域都有复选框,其中一些复选框水平、垂直或与文本组合对齐。此外,我尝试构建的解决方案需要无模板。这是一个形状检测器示例,您可以使用该示例仅检测正方形(您的复选框):希望有帮助…已经参考了该示例和stackoverflow中的大量线程。但是我仍然无法找到如何避免文本区域。谢谢。但是当我在真实数据上尝试代码时,它仍然不起作用。尝试调整阈值和近似输入图像的长度。图像:对我有效,请尝试更改
阈值\u max_面积
到3000。我用这个新输入添加了输出image@nathancy,这看起来很棒。但是,有没有办法识别复选框是否被选中?@Kalaschnik是的,同样的问题,你有没有找到办法?
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)
import cv2

# Load image, convert to grayscale, Otsu's threshold
image = cv2.imread("1.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Find contours, filter using contour approximation, aspect ratio, and contour area
threshold_max_area = 550
threshold_min_area = 100
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
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 len(approx) == 4 and area < threshold_max_area and area > threshold_min_area and (aspect_ratio >= 0.9 and aspect_ratio <= 1.1):
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)

cv2.imshow("image", image)
cv2.imshow("thresh", thresh)
cv2.waitKey()