# strange warpAffine precision issue

I am trying to use OpenCVs warpAffine to transform an image. I use the bilinear interpolation option (set by default). When using a very small transformation (e.g., translation of 0.01 pixel), the transformed image is exactly identical to the original. This is problematic since I need a big precision as further computations are performed on the transformed image.

Example:

Mat img_test = (Mat_<double>(5,5) << 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
Mat tfm; Mat transf_img_test;
tfm = Mat::eye(2,3,CV_64F);
tfm.at<double>(0,2) = 0.01;
warpAffine( img_test, transf_img_test, tfm, img_test.size(), INTER_LINEAR);
cout << "Original = " << img_test << endl;
cout << "Transformed = " << transf_img_test << endl;


The two images are exactly identical:

Original = [0, 0, 0, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 0, 0, 0]
Transformed = [0, 0, 0, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 0, 0, 0]


Note that when I set

tfm.at<double>(0,2) = 0.5


instead, warpAffine correctly transforms (and interpolates) the image.

edit retag close merge delete

Sort by ยป oldest newest most voted

I tried different values and I compared with my own implementation (I use a classical bilinear interpolation). The results are the following (if my code is right, with OpenCV 2.4.11):

Original =
[8, 0, 0, 2, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 3;
0, 5, 0, 0, 0]
tfm =
[1, 0, 0.4;
0, 1, 0]
Transformed =
[4.75, 3.25, 0, 1.1875, 0.8125;
0, 0, 0.59375, 0.40625, 0;
0, 0, 0.59375, 0.40625, 0;
0, 0, 0.59375, 0.40625, 1.78125;
0, 2.96875, 2.03125, 0, 0]
Custom Transformed =
[4.8, 3.2, 0, 1.2, 0.7999999999999998;
0, 0, 0.6000000000000001, 0.3999999999999999, 0;
0, 0, 0.6000000000000001, 0.3999999999999999, 0;
0, 0, 0.6000000000000001, 0.3999999999999999, 1.8;
1.2, 3, 2, 0, 0]

Original =
[8, 0, 0, 2, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 3;
0, 5, 0, 0, 0]
tfm =
[1, 0, 0.3;
0, 1, 0]
Transformed =
[5.5, 2.5, 0, 1.375, 0.625;
0, 0, 0.6875, 0.3125, 0;
0, 0, 0.6875, 0.3125, 0;
0, 0, 0.6875, 0.3125, 2.0625;
0, 3.4375, 1.5625, 0, 0]
Custom Transformed =
[5.6, 2.4, 0, 1.4, 0.5999999999999996;
0, 0, 0.7, 0.2999999999999998, 0;
0, 0, 0.7, 0.2999999999999998, 0;
0, 0, 0.7, 0.2999999999999998, 2.100000000000001;
0.9000000000000001, 3.5, 1.5, 0, 0]

Original =
[8, 0, 0, 2, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 3;
0, 5, 0, 0, 0]
tfm =
[1, 0, 0.35;
0, 1, 0]
Transformed =
[5.25, 2.75, 0, 1.3125, 0.6875;
0, 0, 0.65625, 0.34375, 0;
0, 0, 0.65625, 0.34375, 0;
0, 0, 0.65625, 0.34375, 1.96875;
0, 3.28125, 1.71875, 0, 0]
Custom Transformed =
[5.2, 2.8, 0, 1.3, 0.7000000000000002;
0, 0, 0.6499999999999999, 0.3500000000000001, 0;
0, 0, 0.6499999999999999, 0.3500000000000001, 0;
0, 0, 0.6499999999999999, 0.3500000000000001, 1.95;
1.05, 3.25, 1.75, 0, 0]

Original =
[8, 0, 0, 2, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 0;
0, 0, 1, 0, 3;
0, 5, 0, 0, 0]
tfm =
[1, 0, 0.355;
0, 1, 0]
Transformed =
[5.25, 2.75, 0, 1.3125, 0.6875;
0, 0, 0.65625, 0.34375, 0;
0, 0, 0.65625, 0.34375, 0;
0, 0, 0.65625, 0.34375, 1.96875;
0, 3.28125, 1.71875, 0, 0]
Custom Transformed =
[5.16, 2.84, 0, 1.29, 0.71;
0, 0, 0.645, 0.355, 0;
0, 0, 0.645, 0.355, 0;
0, 0, 0.645, 0.355, 1.935;
1.065, 3.225, 1.775, 0, 0]

Original =
[8, 0, 0, 2, 0;
0, 0, 1, 0, 0;
0, 0, 1 ...
more

Thanks Eduardo. I just implemented my own warpAffine function, and it achieves the desired accuracy, even though running time is much worse than OpenCV's warpAffine. This goes in the direction of your explanation, and it seems that OpenCV's warpAffine sacrifices precision for performance...

( 2015-05-28 02:37:15 -0600 )edit

I have same problem with warpAffine too, MATLAB imwarp vs C++ warpAffine. can you share your implementation for warpAffine. thank you

( 2017-12-26 03:53:19 -0600 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Seen: 630 times

Last updated: May 27 '15