检测是否使用opencv选中该复选框

时间:2018-02-19 12:26:14

标签: python opencv computer-vision

我想找一个复选框([Checked Checkbox])1

是否检查了

。直到现在我尝试使用pyimagesearch中使用的方法。我试图查看图像中是否有任何三角形。如果至少有一个三角形,则表示选中了复选框。我发现的问题是,有时检测外部矩形而不是三角形。我应该如何忽略矩形并仅检测三角形

2 个答案:

答案 0 :(得分:8)

我认为您甚至不需要使用层次结构信息,只需计算轮廓数量并使用它来对图像进行分类。 我给出了一个简单的python实现来查看各个轮廓。

此处已解释了OpenCV中的轮廓层次结构表示Contour Hierachy

img = cv2.imread(r'D:/Image/cross.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,bw = cv2.threshold(gray,220,255,cv2.THRESH_BINARY_INV)
_,contours,hierarchy = cv2.findContours(bw, cv2.RETR_CCOMP,1)
cntLen = 10
ct = 0 #number of contours
for cnt in contours:
    if len(cnt) > cntLen: #eliminate the noises
        ct += 1
        newimg = img.copy()
        cv2.drawContours(newimg,[cnt],0,(0,0,255),2)
        cv2.imshow('Win', newimg)
        cv2.waitKey(0)
print('Total contours: ',ct)

答案 1 :(得分:3)

我最终需要做与此类似的事情,并且不得不确定2500欧元的信封上是否有支票。使用此处的答案,我能够以大约10%的错误率做到这一点。我最终做了以下事情,而不是:

首先,我通过PixelDensity脚本输入了“未经检查”的样本。我正在检查“白色”像素的数量:

import cv2
import numpy as np
from pathlib import Path
from os import listdir
import functools

whitePixelAverage = []

path = "./"
included_extensions = ['png','PNG']

allFiles = [f for f in listdir(path) if any(f.endswith(ext) for ext in included_extensions)] # Get all files in current directory

length = len(allFiles)

for i in range(length):
    img = cv2.imread(allFiles[i], cv2.IMREAD_GRAYSCALE)
    imgCrop = img[655:713,692:767] # Select your ROI here, I allow for a bit of deviation between image scans
    n_white_pix = np.sum(imgCrop == 255)
    print('number of white pixels: ', n_white_pix)
    whitePixelAverage.append(n_white_pix)
print(whitePixelAverage)
print("Average: ", functools.reduce(lambda x, y: x + y,whitePixelAverage)/len(whitePixelAverage))
print("Lowest: ", min(whitePixelAverage))
print("highest: ", max(whitePixelAverage))

t = input(":") # Wait for input to close

从此选择中,我最终获得了“最低”值,并将其阈值设置为3%(在我的情况下为117)。

现在,我也这样做,但是这次向它提供了一个“已选中”框的示例。这些像素的白色像素密度平均应该较低。

对于我的复选框,我使用平均值。最后,我将“已选中”框的“平均值”与未选中的“最低+阈值”进行了比较:

from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import imutils
import cv2
from pathlib import Path
from os import listdir
import os
import shutil
import functools

path = "./testSet/"
checkedP = "./testSet/checked/"
uncheckedP = "./testSet/unchecked/"
included_extensions = ['png','PNG']

THRESHOLD = 117

allFiles = [f for f in listdir(path) if any(f.endswith(ext) for ext in included_extensions)] # Get all files in current directory

length = len(allFiles)

for i in range(length):
    img = cv2.imread(path+allFiles[i])
    imgCrop = img[655:713,692:767]
    gray = cv2.cvtColor(imgCrop, cv2.COLOR_BGR2GRAY)
    ret,bw = cv2.threshold(gray,220,255,cv2.THRESH_BINARY_INV)
    _,contours,hierarchy = cv2.findContours(bw, cv2.RETR_CCOMP,1)
    cntLen = 1
    ct = 0 #number of contours
    for cnt in contours:
        if len(cnt) > cntLen: #eliminate the noises
            ct += 1
    print('Total contours: ',ct)
    if ct >= 3:
        print("Checked!")
        shutil.move(path + allFiles[i], checkedP + allFiles[i])
        img = cv2.imread(checkedP+allFiles[i], cv2.IMREAD_GRAYSCALE)
        imgCrop = img[655:713,692:767]
        n_white_pix = np.sum(imgCrop == 255)
        if (n_white_pix > 3747+THRESHOLD):
            shutil.move(checkedP + allFiles[i], checkedP+"Unconfident/")
        averageWhitePixels.append(n_white_pix)
    else:
        print("Not so checked")
        shutil.move(path + allFiles[i], uncheckedP + allFiles[i])
        img = cv2.imread(uncheckedP+allFiles[i], cv2.IMREAD_GRAYSCALE)
        imgCrop = img[655:713,692:767]
        n_white_pix = np.sum(imgCrop == 255)
        if (n_white_pix < 3747+THRESHOLD):
            shutil.move(uncheckedP + allFiles[i], uncheckedP+"Unconfident/")

除了对Flamelite的回答进行比较之外,我还可以将像素密度在2500个不同的样本中从10%降低到约2.47%。

我很抱歉我的代码多么不雅。这是我的第一个答案,如果有什么不好的话请告诉我。我很可能在其中留了很多东西来进行故障排除。

希望这会有所帮助!