我正在尝试使用OpenCV和python创建一张纸上的孔检测器。我已经训练了可成功识别漏洞的自定义SVM。我用125个底片和100个正片(100像素x 100像素)训练了它。 10%用于测试;给出了100%的准确性(我打算扩展数据集,但目前只是试图使其以某种方式工作)。
我正在尝试使猪用多尺度检测器工作,以便可以查看它是否可以正确识别完整图像中的孔。培训者将SVM输出为XML,我使用this answer来为HOG加载自定义SVM。我有一个get hog函数,训练器和检测器都使用。
def get_hog() :
winSize = (100,100)
blockSize = (20,20)
blockStride = (10,10)
cellSize = (10,10)
nbins = 9
derivAperture = 1
winSigma = -1.
histogramNormType = 0
L2HysThreshold = 0.2
gammaCorrection = 1
nlevels = 64
signedGradient = True
hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins,derivAperture,winSigma,histogramNormType,L2HysThreshold,gammaCorrection,nlevels, signedGradient)
return hog
检测器看起来像:
tree = ET.parse('digits_svm.xml')
root = tree.getroot()
# now this is really dirty
SVs = root.getchildren()[0].getchildren()[-2].getchildren()[0]
rho = float( root.getchildren()[0].getchildren()[-1].getchildren()[0].getchildren()[1].text )
svmvec = [float(x) for x in re.sub( '\s+', ' ', SVs.text ).strip().split(' ')]
svmvec.append(-rho)
from train_digits import get_hog
# initialize the HOG descriptor/person detector
hog= get_hog()
hog.setSVMDetector( np.array(svmvec) )
# loop over the image paths
for imagePath in paths.list_images(args["images"]):
# load the image and resize it to (1) reduce detection time
# and (2) improve detection accuracy
image = cv2.imread(imagePath)
image = imutils.resize(image, width=min(400, image.shape[1]))
orig = image.copy()
# detect holes in the image
(rects, weights) = hog.detectMultiScale(image, winStride=(8, 8),
padding=(8, 8), finalThreshold=0, scale=1.05)
# draw the original bounding boxes
for (x, y, w, h) in rects:
cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)
# apply non-maxima suppression to the bounding boxes using a
# fairly large overlap threshold to try to maintain overlapping
# boxes that are still holes
rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)
# draw the final bounding boxes
for (xA, yA, xB, yB) in pick:
cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)
# show some information on the number of bounding boxes
filename = imagePath[imagePath.rfind("/") + 1:]
print("[INFO] {}: {} original boxes, {} after suppression".format(
filename, len(rects), len(pick)))
# show the output images
cv2.imshow("Before NMS", orig)
cv2.imshow("After NMS", image)
cv2.waitKey(0)
问题在于,当finalThreshold = 2(默认值)时,我在图像中心得到一个框。仔细查看发生了什么(设置finalThreshold = 0),发现检测器认为一切都是一个漏洞。
[ INFO:0] Initialize OpenCL runtime...
[INFO] IMG_0468.jpg: 18134 original boxes, 5 after suppression
Image with boxes before and after non-maxima suppression
我不确定是什么原因导致检测器对所有东西都返回正值,我一直在处理一些参数,其中一些会使情况变得更好,而其他会使情况变得更糟。但是没有一个有很大的改善。有什么想法可能导致这种情况?谢谢