1 | initial version |
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, 0, 0;
0, 0, 1, 0, 3;
0, 5, 0, 0, 0]
tfm =
[1, 0, 0.34;
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.279999999999999, 2.720000000000001, 0, 1.32, 0.6799999999999997;
0, 0, 0.6599999999999999, 0.3399999999999999, 0;
0, 0, 0.6599999999999999, 0.3399999999999999, 0;
0, 0, 0.6599999999999999, 0.3399999999999999, 1.98;
1.02, 3.3, 1.7, 0, 0]
It looks like the output of warpAffine is (bit-)troncated to a certain precision.
0.59375 <==> 0x3fe3000000000000
0.6875 <==> 0x3fe6000000000000
0.65625 <==> 0x3fe5000000000000
Just a supposition but my guess is that in order to have good performance, the bilinear interpolation used in warpAffine is deliberately limited to a certain precision (e.g. using a fast but approximate interpolation method).
To really understand what happens, I think that the best option would be to look into the source code (OpenCV 2.4.11, OpenCV 3.0.0) but I am not good enough to understand it.
Not really a solution but you could implement yourself the warpAffine function if you have a precision constraint and if the performance is not too critical ?