python opencv人检测

时间:2018-03-29 11:53:36

标签: python opencv

我正在尝试使用opencv和python构建一个人员检测功能,但我需要一些帮助来理解一些事情。 图像来自手机录制到窗口。 这是代码:

# USAGE
# python detect.py --images images

from __future__ import print_function
from glob import glob
from imutils.object_detection import non_max_suppression
import argparse
import cv2
import numpy as np
import os

# parse arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--images", required=True, help="path to images directory")
args = vars(ap.parse_args())

# strip last / if present
arg_images = args["images"].rstrip("/")

# check folder exists
if not os.path.isdir(arg_images):
    print(arg_images + " is not a folder, terminate")
    quit()

# load images names
imagePaths = sorted(glob(arg_images + "/*.jpg"))
# check folder is not empty
if len(imagePaths) == 0:
    print(arg_images + " is empty, terminate")
    quit()

hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

for imagePath in imagePaths:
    # INTER_NEAREST - a nearest-neighbor interpolation
    # INTER_LINEAR - a bilinear interpolation (used by default)
    # INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
    # INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
    # INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood
    image = cv2.imread(imagePath)
    image = cv2.resize(image, (min(800, image.shape[1]), min(600, image.shape[0])), interpolation = cv2.INTER_LINEAR)
    #image = cv2.resize(image, (min(1200, image.shape[1]), min(900, image.shape[0])), interpolation = cv2.INTER_LINEAR)

    (rects, weights) = hog.detectMultiScale(image, winStride=(4, 4), padding=(0, 0), scale=1.01)

    foldername = imagePath[0:imagePath.rfind("/")]
    filename = imagePath[imagePath.rfind("/") + 1:]

    if len(rects) == 0:
        print("- " + filename)
    else:
        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)

        for (xA, yA, xB, yB) in pick:
            cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)

        print("+ " + filename)
        cv2.imwrite(foldername + "/detected/" + filename, image)

当我在这些图像(test.zip)上运行此功能时,根据图像大小,我会得到非常不同的结果:

  • 800x600:误报率最低,夜间约为40%,白天约为10%
  • 1200x900:更多误报
  • 原始大小:看起来更像是随机猜测而不是检测

我可以假设它是因为detectMultiScale使用一个小的检测窗口,我可以改变步幅,但不能改变大小?

另外,如果你看一下IMG_20180329_061603.jpg这是一个总是检测到误报,但我不明白为什么。夜晚的照片看起来都是一样的(对我来说),但有太多的照片可以得到一个绿色的盒子..

欢迎任何帮助。如果您需要澄清,请询问.. 感谢

1 个答案:

答案 0 :(得分:0)

您看到的原因是用于人员检测的HOG描述符具有64x128窗口。因此,您希望优化scale参数和图像大小,以获得大多数真正的积极因素。你可能最关心的是一个人靠近自行车,所以那些远(并且很小)的人并不那么重要。我会收集一组“训练”图像以找到最佳的参数值。此外,您忽略了detectMultiScale()返回的权重,您可以再次将这些值显示为真阳性和误报,并找到最佳阈值。