Ask Your Question
1

Segmentation fault when initializing tracker. Possible bug?

asked 2016-12-07 01:16:43 -0600

kurene13 gravatar image

Hello,

I'm reporting the issue for the first time, so below is all information I think you need to check for a bug. There is a possible bug in tracking API. Below is a detailed description.

In my project I'm using opencv2/tracking.hpp header and Ptr<cv::Tracker> tracker object. Tracker is created with line: tracker = cv::Tracker::create("KCF");. It's initialized with following code:

// If tracker is not empty we want it to reinitialize.
if(tracker->getModel()){
    tracker->clear();
    tracker = cv::Tracker::create("KCF");
}
// Initialize tracker
if(!tracker->init(frame, roi)){
    cerr << "Could not initialize tracker" << endl;
    exit(EXIT_FAILURE);
}

When initializing I'm using a cv::Mat frame from a video and cv::Rect2d roi as bounding box that is read from a file. These two parameters are downscaled before usage. They are downscaled by factor 25%. Frame is scaled with cv::resize(), and bounding box is scaled with following code:

outputRoi = inputRoi;

double scaledWidth = (inputRoi.width*(scaleFactor));
double scaledHeight = (inputRoi.height*(scaleFactor));

// using ratio
outputRoi.x = (scaledWidth/inputRoi.width*inputRoi.x);
outputRoi.y = (scaledHeight/inputRoi.height*inputRoi.y);
outputRoi.width = scaledWidth;
outputRoi.height = scaledHeight;

When I don't scale, code is working fine. If I scale and for bounding box use cvRound for x, y, width and height it is working. If I scale and don't use rounding I get segmentation fault for specific bounding box on specific frame. For other frames it is working fine. The fact is that init method is defined as bool init( const Mat& image, const Rect2d& boundingBox ) and should be working with "unrounded" double values.

Here is main.cpp code for testing. Uncomment or comment scaleRoiNotWorking and scaleRoiWorking and different roi values to see the difference.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   main.cpp
 * Author: gregork
 *
 * Created on December 7, 2016, 7:39 AM
 */

#include <cstdlib>
#include <opencv2/tracking.hpp>

using namespace std;
using namespace cv;


static void scaleFrame(const InputArray& inputImage, OutputArray& outputImage, double scaleFactor){
    cv::resize(inputImage, outputImage, Size(), scaleFactor, scaleFactor);
}

static void scaleRoiNotWorking(const Rect2d& inputRoi, Rect2d& outputRoi, double scaleFactor){
    outputRoi = inputRoi;
    double scaledWidth = (inputRoi.width*(scaleFactor));
    double scaledHeight = (inputRoi.height*(scaleFactor));

    // Using ratio / proportion
    outputRoi.x = (scaledWidth/inputRoi.width*inputRoi.x);
    outputRoi.y = (scaledHeight/inputRoi.height*inputRoi.y);
    outputRoi.width = scaledWidth;
    outputRoi.height = scaledHeight;
}

static void scaleRoiWorking(const Rect2d& inputRoi, Rect2d& outputRoi, double scaleFactor){
    outputRoi = inputRoi;

    double scaledWidth = cvRound(inputRoi.width*(scaleFactor));
    double scaledHeight = cvRound(inputRoi.height*(scaleFactor));

    // Using ratio / proportion
    outputRoi.x = cvRound(scaledWidth/inputRoi.width*inputRoi.x);
    outputRoi.y = cvRound(scaledHeight/inputRoi.height*inputRoi.y);
    outputRoi.width = scaledWidth;
    outputRoi.height = scaledHeight;
}

int main(int argc, char** argv) {
    Mat frame = Mat::ones(Size(1920,1080), CV_8UC3);
    /*frame = imread(argv[1], CV_LOAD_IMAGE_COLOR);
    if(! frame.data )                              // Check for invalid input
    {
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    }*/
    scaleFrame(frame, frame, 0.25);

//
    Rect2d origRoi(817, 251, 340, 613 ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-12-07 02:04:54 -0600

LBerger gravatar image

updated 2016-12-07 02:17:55 -0600

Yes I think it's a bug :

line

 // create gaussian response
y=Mat::zeros((int)roi.height,(int)roi.width,CV_64F);
for(unsigned i=0;i<roi.height;i++){
  for(unsigned j=0;j<roi.width;j++){
    y.at<double>(i,j)=(i-roi.height/2+1)*(i-roi.height/2+1)+(j-roi.width/2+1)*(j-roi.width/2+1);
  }
}

when you roi.height is a double value (int)roi.height is not equal roi.height then in loop pixels outside are scanned. Loop should be something like this:

 y=Mat::zeros(static_cast<int>(roi.height),static_cast<int>(roi.width),CV_64F);

 for(unsigned i=0;i<y.rows;i++){
   for(unsigned j=0;j<y.cols;j++){

About issue now I cannot find it https://github.com/opencv/opencv_cont.... If you don't report it you can do it

edit flag offensive delete link more

Comments

now if you want you can make a pull request to solve bug. You can follow this good post

LBerger gravatar imageLBerger ( 2016-12-07 02:41:23 -0600 )edit

when you roi.height is a double value (int)roi.height is not equal roi actually it will be downscaled to the lower int value so this would not generate an issue. This is purely because a matrix cannot be initialized with double values.

StevenPuttemans gravatar imageStevenPuttemans ( 2016-12-07 03:08:10 -0600 )edit
1

(int)125.3 = 125 and then for (int i=0; i<125.3;i++) row i=125 is scanned and exception

LBerger gravatar imageLBerger ( 2016-12-07 03:28:00 -0600 )edit

I do not think so. The unsigned will force an integer comparison and thus the 125.3 will be rounded ...

StevenPuttemans gravatar imageStevenPuttemans ( 2016-12-07 03:53:35 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-12-07 01:16:43 -0600

Seen: 1,317 times

Last updated: Dec 07 '16