I\'m trying to optimize this code, in particular:
bool interpolate(const Mat &im, float ofsx, float ofsy, float a11, float a12, float a21, float a22, Mat
I'm more familiar with this warpAffine, whose basic statement is
cv::warpAffine (InputArray src, // input mat
OutputArray dst, // output mat
InputArray M, // affine transformation mat
Size dsize) // size of the output mat
where M
is the matrix
a11 a12 ofx
a21 a22 ofy
In your term, the first two columns is the linear transformation matrix A
, the last is the translation vector b
.
The cv::hal::warpAffine()
is just the same, where double M[6]
corresponds to the above affine transformation matrix, but I'm not sure in which order it is flatten (most likely, [a11,a12,ofx,a21,a22,ofy]
).
In OpenCV, the origin (0,0)
is the top-left conner as usual, while in Intel's code, the origin (0,0)
is in the middle of the image. That's what the part
for (int j=-halfHeight; j<=halfHeight; ++j)
{
for(int i=-halfWidth; i<=halfWidth; ++i)
{
const int y = (int) floor(wy);
//...
}
}
does: (i,j)
is the coordinate in res
, j from -halfHeight to halfHeight
and i from -halfHeight to halfHeight
. So in this case (0,0)
is in the center of the res
image.
In the provided code, if you want to map src
onto res
(i guess), you would need to do:
bool touchesBoundary = interpolate(smoothed, (float)(imageSize>>1), (float)(imageSize>>1), imageToPatchScale, 0, 0, imageToPatchScale, patch);
Notice here imageSize>>1
instead of patchImageSize>>1
. Why? You want the center of the res
(i=0,j=0
) maps to the center of src
, i.e. the value src.at<float>(src.cols/2, src.rows/2)
(why?)
Now to make that work in your example, the equivalent of cv::warpedAffine()
would be
warpAffine(smoothed, myPatch, warp_mat, patch.size(),WARP_INVERSE_MAP);
where the warp_mat
has ofsx=0,ofsy=0
.
Finally, here's an illustration of what I tried:
where diff = mypatch - patch >5
and smoothed
is scaled up by OS. Notice the black border in patch
, it is because the restrictions x < width
and y<height
in the code.