Ask Your Question

Revision history [back]

click to hide/show revision 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 ?