How can I rewrite this warp-affine using OpenCV?

后端 未结 1 481
旧巷少年郎
旧巷少年郎 2020-12-20 07:53

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         


        
相关标签:
1条回答
  • 2020-12-20 08:13

    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.

    0 讨论(0)
提交回复
热议问题