# Bug in warpAffine?

I think the following examples shows a bug in warpAffine:

   Mat x(1,20, CV_32FC1);
for (int iCol(0); iCol<x.cols; iCol++) { x.col(iCol).setTo(iCol); }
Mat crop;
Point2d c(10., 0.);
double scale(1.3);
int cropSz(11);
double vals[6] = { scale, 0.0, c.x-(cropSz/2)*scale, 0.0, scale, c.y };
Mat map(2, 3, CV_64FC1, vals);
warpAffine(x, crop, map, Size(cropSz, 1), WARP_INVERSE_MAP |  INTER_LINEAR);
float dx = (crop.at<float>(0, crop.cols-1) - crop.at<float>(0, 0))/(crop.cols-1);
Mat constGrad = crop.clone().setTo(0);
for (int iCol(0); iCol<constGrad.cols; iCol++) {
constGrad.col(iCol) = c.x + (iCol-cropSz/2)*scale;
}
Mat diff = crop - constGrad;
double err = norm(diff, NORM_INF);
if (err>1e-4) {
cout << "Problem:" << endl;
cout << "computed output: " << crop << endl;
cout << "expected output: " << constGrad << endl;
cout << "difference: " << diff << endl;
Mat dxImg;
Mat dxFilt(1, 2, CV_32FC1);
dxFilt.at<float>(0) = -1.0f;
dxFilt.at<float>(1) = 1.0f;
filter2D(crop, dxImg, crop.depth(), dxFilt);
cout << "x-derivative in computed output: " << dxImg(Rect(1,0,10,1)) << endl;
cout << "Note: We expect a constant difference of 1.3" << endl;
}


Here is the program output:

Problem:
computed output: [3.5, 4.8125, 6.09375, 7.40625, 8.6875, 10, 11.3125, 12.59375, 13.90625, 15.1875, 16.5]
expected output: [3.5, 4.8000002, 6.0999999, 7.4000001, 8.6999998, 10, 11.3, 12.6, 13.9, 15.2, 16.5]
difference: [0, 0.012499809, -0.0062499046, 0.0062499046, -0.012499809, 0, 0.012499809, -0.0062503815, 0.0062503815, -0.012499809, 0]
x-derivative in computed output: [1.3125, 1.28125, 1.3125, 1.28125, 1.3125, 1.3125, 1.28125, 1.3125, 1.28125, 1.3125]
Note: We expect a constant difference of 1.3


I create an image with entries 0, 1, 2, ...n-1, and cut a region around (10,0) with scale 1.3. I also create an expected image constGrad. However, they are not the same. Even more, since the input image has a constant derivative in x-direction and the mapping is affine, I expect also a constant gradient in the resulting image. The problem is not a boundary stuff problem, the same happens at the inner of an image. It's also not related to WARP_INVERSE_MAP.

Is this a known issue? any comments on this?

edit retag close merge delete

1

I'm pretty sure this is your problem, not warpAffine. For one thing, you've got an int division rounding error. cropSz/2 and cropSz/2.0 are not the same thing.

( 2016-11-28 11:06:47 -0500 )edit

The rounding error is what I want here. I don't see my error in the code. If you see it, please tell me. I also added a sanity check which shows, that something strange is going on.

( 2016-11-29 04:30:47 -0500 )edit

Sort by ยป oldest newest most voted

Okay, I see what you're doing. Not sure why you didn't just do 1.3*iCol+3.5, but whatever.

You're seeing the effects of a couple of rounds and the interpolation. You get better results with INTER_LANCOSZ4. warpAffine is for images, not math.

If you want to have mathematical precision, use the function transform(). It takes a small amount of setup, but you get math accurate results. Basically, add another channel of all 0 to be the Y component.

more

Thanks for your reply. My actual goal is to take advantage of symmetry. However I noticed, that croping an rotated rectangle from an image and flipping does not give the same result than flipping the whole image and cropping the transformed rotated rectangle. I boiled it down to that problem. I see your point that round off errors can be neglected in many applications in CV, however, I would not make a distinction between math and images. I think it is strange, that we see such a huge roundoff error in a linear interpolation (float has an precission of 1e-6 which is 4 orders af magnitudes below the error). Anyway, thanks a lot.

( 2016-11-30 01:55:50 -0500 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2016-11-28 04:57:23 -0500

Seen: 236 times

Last updated: Nov 29 '16