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

Python 检测是否使用opencv选中该复选框,python,opencv,computer-vision,Python,Opencv,Computer Vision,我正在尝试查找是否有复选框([]) 是否检查。到目前为止,我一直在尝试使用中使用的方法。我正在尝试查看图像中是否有任何三角形。如果至少有一个三角形,则表示复选框已选中。我发现的问题是,有时会检测到外部矩形而不是三角形。如何忽略矩形而只检测三角形我认为您甚至不需要使用层次结构信息,只需计算轮廓的数量并用于对图像进行分类。 我给出了一个简单的python实现来查看各个轮廓 这里已经解释了OpenCV中的轮廓层次表示 我最终需要做一些与此非常类似的事情,并且必须确定2500个ish信封是否有检查。使用

我正在尝试查找是否有复选框([])


是否检查。到目前为止,我一直在尝试使用中使用的方法。我正在尝试查看图像中是否有任何三角形。如果至少有一个三角形,则表示复选框已选中。我发现的问题是,有时会检测到外部矩形而不是三角形。如何忽略矩形而只检测三角形

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

这里已经解释了OpenCV中的轮廓层次表示


我最终需要做一些与此非常类似的事情,并且必须确定2500个ish信封是否有检查。使用这里的答案,我能够以大约10%的错误率完成它。我最终做了以下几件事:

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

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/")
从imutils.perspective导入四点变换
从imutils导入等高线
将numpy作为np导入
导入imutils
进口cv2
从pathlib导入路径
从操作系统导入listdir
导入操作系统
进口舒蒂尔
导入功能工具
path=“./testSet/”
checkedP=“./testSet/checked/”
取消选中dp=“./testSet/unchecked/”
包含的_扩展=['png','png']
阈值=117
allFiles=[f代表listdir(路径)中的f,如果有的话(f.endswith(ext)代表包含的扩展名中的ext)]获取当前目录中的所有文件
长度=len(所有文件)
对于范围内的i(长度):
img=cv2.imread(路径+所有文件[i])
imgCrop=img[655:713692:767]
灰色=cv2.CVT颜色(imgCrop,cv2.COLOR\U BGR2GRAY)
ret,bw=cv2.阈值(灰色,220255,cv2.阈值\u二进制\u INV)
_,等高线,层次=cv2.findContours(bw,cv2.RETR_CCOMP,1)
cntLen=1
ct=0#轮廓数
对于轮廓中的cnt:
如果len(cnt)>cntLen:#消除噪音
ct+=1
打印('总轮廓:',ct)
如果ct>=3:
打印(“选中!”)
move(path+allFiles[i],checkedP+allFiles[i])
img=cv2.imread(checkedP+allFiles[i],cv2.imread\u灰度)
imgCrop=img[655:713692:767]
n_white_pix=np.sum(imgCrop==255)
如果(n_white_pix>3747+阈值):
move(checkedP+allFiles[i],checkedP+“Unconfident/”)
averageWhitePixels.append(n_white_pix)
其他:
打印(“未如此检查”)
move(path+allFiles[i],取消选中dp+allFiles[i])
img=cv2.imread(取消选中dp+allFiles[i],cv2.imread\u灰度)
imgCrop=img[655:713692:767]
n_white_pix=np.sum(imgCrop==255)
如果(n_white_pix<3747+阈值):
move(uncheckedP+allFiles[i],uncheckedP+“Unconfident/”)
比较像素密度和flamelite的答案,我能够将2500个不同样本的错误率从10%降低到2.47%

我很抱歉我的代码太不雅观了。这是我的第一个答案,如果有什么事情太可怕,请告诉我。很可能还有很多我用来排除故障的东西


希望这有帮助

PylageSearch的教程能够根据顶点区分不同的形状。。你为什么不用它?我试过了。我用了哈里斯角探测器。但是,我在图片中得到了太多的分数。我已经解决了这个任务。我有一个选中/未选中复选框的数据集,并根据这些数据构建了分类器。我尝试过随机森林,KNN和这两种算法给了我几乎完美的结果。而且速度也很快。数据集非常小,每个classi guess图像约40个样本包含矩形(未选中)或带对角线的矩形(已选中),在这种情况下,您可以检查像素密度并使用特定的预定义阈值对其进行分类。或者你可以分析轮廓层次来分类。@ChauLoi很抱歉回复得太晚了。如果我没有弄错的话,我只使用了原始像素,并将它们输入分类器。嘿,我想知道你是否有更好的方法,因为这种方法对我的情况不好。请查看我的作品:
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/")