Ask Your Question
2

Sobel filter doesn't respect ROI

asked 2013-08-21 16:48:36 -0600

mkeeter gravatar image

I'm suspicious about how the Sobel filter treats non-continuous images.

Two identical images -- one made by changing the ROI of a larger image and the other by cloning -- produce different results when run through the filter:

#include <cassert>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
    // Create a matrix that is all-zeros other than the last column
    Mat orig(100, 100, CV_8U, cv::Scalar(0)), copy;
    orig.col(orig.cols-1).setTo(255);

    // Crop the last column out of the matrix in two ways:
    //  a) Using colRange, which only creates a new header
    //  b) Using copyTo, which creates a new header and data
    orig = orig.colRange(0, orig.cols - 1);
    orig.copyTo(copy);

    // Assert that the matrices are the same
    assert(countNonZero(orig != copy) == 0);

    // Run a Sobel filter on both matrices
    Sobel(orig, orig, CV_16S, 1, 0);
    Sobel(copy, copy, CV_16S, 1, 0);

    // Assert that the Sobel filter results are the same
    assert(countNonZero(orig != copy) == 0);
}

This bit of sample code fails on the second assert statement.

(OpenCV 2.4.6.1 on Mac OS 10.6, 64-bit)

edit retag flag offensive close merge delete

Comments

You should report your bug on the bug tracker. Thanks.

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2013-08-21 17:48:41 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
3

answered 2014-10-08 03:53:32 -0600

As reported in the bug report this behaviours is completely normal.

AFAIK copyTo only couples the header of the new Mat element with the header of the original file. In memory they are still pointing to the same data. The clone() operation makes a deep copy and ensures that a pointer to new memory is created.

So basically it is normal that your code produces two different results. The first Sobel is on the original data, however the second Sobel is applied on an already Sobel applied image and thus the end result will be different.

I suggest adjusting this line

orig.copyTo(copy);

to

copy = orig.clone();

And the result will be as expected.

The logic behind is the use of smart pointers in OpenCV which try to minimize the memory print of an application but which can lead to very unexpected behaviour.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2013-08-21 16:48:36 -0600

Seen: 683 times

Last updated: Oct 08 '14