Ask Your Question

b1's profile - activity

2017-08-01 12:23:31 -0600 asked a question Problems with OpenCV GPU accelerated HOG detect

I am running a TX1 with OpenCV4Tegra 2.4.13 alongside ROS Kinetic on Ubuntu 16.04. I am attempting to get a very primitive people detector setup and am scratching my head at the error I am receiving when the application is run:

OpenCV Error: Assertion failed (padding == Size(0, 0)) in detect, file /hdd/buildbot/slave_jetson_tx_3/35-O4T-L4T-R24/opencv/modules/gpu/src/hog.cpp, line 365
terminate called after throwing an instance of 'cv::Exception'
  what():  /hdd/buildbot/slave_jetson_tx_3/35-O4T-L4T-R24/opencv/modules/gpu/src/hog.cpp:365: error: (-215) padding == Size(0, 0) in function detect

The error seems as if it would be clear enough, however padding should be getting explicitly set to Size(16, 16) and I am unable to track down why it is being seen as equivalent to Size(0,0). I have done simple sanity checks such as creating a variable of type Size and doing the comparison myself before passing it to the function showing that it should not show as equivalent to Size(0,0)

Hacked together source:

using namespace std;

#include <opencv2/opencv.hpp>
#include <opencv2/gpu/gpu.hpp>
#include <stdio.h>
#include <vector>
#include <iostream>
#include "ros/ros.h"
#include "sensor_msgs/Image.h"

cv::Mat image_;
bool new_img_ = false;

void callback(const sensor_msgs::Image::ConstPtr& msg)
{
    if (new_img_) return;
    image_ = cv::Mat((int)msg->width, (int)msg->height, CV_8U, (uint8_t*)&msg->data[0]).clone().reshape(0, msg->height);
    new_img_ = true;
}

int main (int argc, char * argv[])
{
    printf("Using OpenCV %i.%i.%i\n", CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION);
    cv::gpu::HOGDescriptor hog;
    hog.setSVMDetector(cv::gpu::HOGDescriptor::getDefaultPeopleDetector());

    ros::init(argc, argv, "peopleDectector_node");
    ros::NodeHandle n;

    ros::Subscriber sub = n.subscribe("/sensors/camera/color_image", 3, callback);

    while (true)
    {
        if (new_img_) {
            vector<cv::Rect> found;

            cv::gpu::GpuMat gpu_img;
            gpu_img.upload(image_);

            // This next line is the source of all the issues, it claims cv::Size(16,16) == Size(0,0)
            hog.detectMultiScale(gpu_img, found, 1.1, cv::Size(8,8), cv::Size(16,16), 1.05, 2);

            printf("Found %lu people\n", found.size());
            new_img_ = false;
        }
        ros::spinOnce();
    }
    return 0;
}

I've been scratching my head on this one for far too long now. The code works if I transition back to doing the computations on the CPU rather than the GPU which leads me to believe everything is linking appropriately, but to be honest I'm not entirely sure. Thank you in advance for any help!

EDIT: For extra context, here are the two functions that lead up the assertion. From what I can tell, padding isn't even used and the assert should therefor be removed.

void cv::gpu::HOGDescriptor::detect(const GpuMat& img, vector<Point>& hits, double hit_threshold, Size win_stride, Size padding)
{
    CV_Assert(img.type() == CV_8UC1 || img.type() == CV_8UC4);
    CV_Assert(padding == Size(0, 0));

    hits.clear();
    if (detector.empty())
        return;

    computeBlockHistograms(img);

    if (win_stride == Size())
        win_stride = block_stride;
    else
        CV_Assert(win_stride.width % block_stride.width == 0 && win_stride.height % block_stride.height == 0);

    Size wins_per_img = numPartsWithin(img.size(), win_size, win_stride);
    //   labels.create(1 ...
(more)