我正在尝试查找复选框([
])1是否被选中。到目前为止,我尝试使用pyimagesearch中所用的方法。我想检查图像中是否有任何三角形。如果至少有一个三角形,则意味着复选框已被选中。我发现的问题是,有时会检测到外部矩形而非三角形。我应该如何忽略矩形并仅检测三角形?
![Checked Checkbox](https://istack.dev59.com/6am9N.webp)
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)
我最终需要做的事情与这个非常相似,需要确定大约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%。
对于我的代码有多么不优雅,我感到非常抱歉。这是我的第一个答案,请告诉我是否有任何问题。很可能还有很多用于故障排除的东西留在那里。
希望这有所帮助!