【问题标题】:Different results from OpenCV in Python and C++ implementations for HOG object detection用于 HOG 对象检测的 Python 和 C++ 实现中 OpenCV 的不同结果
【发布时间】:2015-10-05 13:09:35
【问题描述】:

我已经使用 OpenCV 在 Python 和 C++ 中实现了 HOG 人脸检测器。我试图让两个实现中的代码完全相同。但是,我在两者中都得到了不同的结果。在 Python 中,它可以正常工作,但是,在 C++ 中,它显示的结果完全不正确。下面是它们的输出示例(第一个在 Python 中,第二个在 C++ 中):

首先,我为这两种实现训练了一个 OpenCV 线性 SVM 分类器,并将它们保存在 XML 文件(模型文件)中。然后,我使用this code 用于Python 实现和this code 用于C++ 实现从模型(XML 文件)中提取系数(用于在测试过程中自定义HOG 检测器)。也就是说,这些系数将在测试过程中作为函数 setSVMDetector(const std::vector input_coefficients) 的输入。

理想情况下,这些系数应该相同,因为它们是从同一数据集并使用 OpenCV 计算的。我通过将它们保存在两个实现的文本文件中手动检查了这些系数值,发现它们几乎相同。因此,我希望我未来定制的 HOG 检测器在两种实现中的工作方式几乎相同。

以下是使用这两种实现在测试图像中检测人脸的测试代码。

Python 实现:

import cv2
im = cv2.imread("..\\test_imgs\\1.png", 0) # test image
hog = cv2.HOGDescriptor((96, 128), (16,16), (8,8), (8,8), 9)

coeffs = pickle.load(open("coeffs_from_model")) # load coeffs already computed from model
hog.setSVMDetector( np.array(coeffs)) # customize HOG detector

found, w = hog.detectMultiScale(im,  winStride=(8,8), padding=(32,32), scale=4.05)
draw_detections(im, found_filtered) # method for drawing BBs on image

C++ 实现:

cv::Mat im = cv::imread("..\\test_imgs\\1.png", 0);
cv::HOGDescriptor hog(cv::Size(96, 128), cv::Size(16, 16), cv::Size(8, 8), cv::Size(8, 8), 9);

LinearSVM svm; // check the link 
svm.load(model.c_str());

std::vector<float> coeffs;
svm.getSupportVector(coeffs); // compute coeffs from model

hog.setSVMDetector(coeffs); // customize HOG detector

std::vector<cv::Rect> found; // holds the detected BBs
hog.detectMultiScale(im, found, 0, cv::Size(8, 8), cv::Size(32, 32), 4.05); 
drawLocations(im, found, cv::Scalar(0, 255, 0)); // method for drawing BBs on the image. 

为了检查为 C++ 计算的系数是否不正确。我在 Python 实现中使用了它们,有趣的是,它们的工作原理完全相同。所以,现在我不明白为什么 C++ 实现中的 HOG 对象尽管具有正确的系数却不能正常工作。

我在 C++ 中使用了与 Python 相同的 HOG 对象初始化,并且在两种实现中保持代码几乎相同,因为它们都使用相同的 OpenCV。

【问题讨论】:

  • 你能证明你的 Python coeffs = pickle.load(open("coeffs_from_model")) 正在做你的 C++ std::vector&lt;float&gt; coeffs; svm.getSupportVector(coeffs); 正在做的事情吗?
  • @boardrider:我在 Python 测试代码中使用了 C++ 实现中计算的系数。而且,它在那里工作完全正确。我也反其道而行之,即在 C++ 测试代码中使用 Python 计算的系数(它已经在工作)。但是,它显示的错误几乎与使用自己的系数(C++ 系数)显示的错误相同。由此,我得出两点结论:(i)系数是正确的(Python 或 C++)和(ii)C++ 实现中存在问题,我仍在努力解决。

标签: python c++ opencv computer-vision object-detection


【解决方案1】:

我现在得到了答案。上面写的两个代码都是正确的。问题在于用于训练的标签。我在两个实现中都使用“0”(人脸类)和“1”(非人脸类)作为标签。

对于 Python 实现,这个标签工作正常,但是,对于 C++ 实现,它似乎必须是“+1”(面类)和“-1”(非面类),因为我发现它@ 987654321@。在该示例中,在源代码的末尾,标签提供为:

// Set up training data
float labels[4] = {1.0, -1.0, -1.0, -1.0};
Mat labelsMat(4, 1, CV_32FC1, labels);

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 2012-08-01
    • 2014-12-02
    • 2012-10-18
    • 2013-01-24
    • 2017-08-13
    相关资源
    最近更新 更多