Search code examples
c#image-processingopencvemgucvperspective

How to make PerspectiveTransform work?


I just want to reproduce the result as posted here.

I rewrite the source to EmguCV form.

    Image<Bgr, byte> image = new Image<Bgr, byte>(@"B:\perspective.png");

    CvInvoke.cvShowImage("Hello World!", image);

    float[,] scrp = { { 43, 18 }, { 280,40}, {19,223 }, { 304,200} };
    float[,] dstp = { { 0,0}, { 320,0}, { 0,240 }, { 320,240 } };
    float[,] homog = new float[3, 3];


    Matrix<float> c1 = new Matrix<float>(scrp);
    Matrix<float> c2 = new Matrix<float>(dstp);
    Matrix<float> homogm = new Matrix<float>(homog);


    CvInvoke.cvFindHomography(c1.Ptr, c2.Ptr, homogm.Ptr, Emgu.CV.CvEnum.HOMOGRAPHY_METHOD.DEFAULT, 0, IntPtr.Zero);
    CvInvoke.cvGetPerspectiveTransform(c1, c2, homogm);

    Image<Bgr, byte> newImage = image.WarpPerspective(homogm, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, Emgu.CV.CvEnum.WARP.CV_WARP_DEFAULT, new Bgr(0, 0, 0));

    CvInvoke.cvShowImage("newImage", newImage);

This is the testing image. enter image description here

The newImage is always a blank image.

Can anyone help me make my source code work???


Solution

  • Hopefully, I found the answer by myself.

    I rewrote the source to the wrong form. I should use Point[] and there is CameraCalibration.GetPerspectiveTransform function to use.

        PointF[] srcs = new PointF[4];
        srcs[0] = new PointF(253, 211);
        srcs[1] = new PointF(563, 211);
        srcs[2] = new PointF(563, 519);
        srcs[3] = new PointF(253, 519);
    
    
        PointF[] dsts = new PointF[4];
        dsts[0] = new PointF(234, 197);
        dsts[1] = new PointF(520, 169);
        dsts[2] = new PointF(715, 483);
        dsts[3] = new PointF(81, 472);
    
        HomographyMatrix mywarpmat = CameraCalibration.GetPerspectiveTransform(srcs, dsts);
        Image<Bgr, byte> newImage = image.WarpPerspective(mywarpmat, Emgu.CV.CvEnum.INTER.CV_INTER_NN, Emgu.CV.CvEnum.WARP.CV_WARP_FILL_OUTLIERS, new Bgr(0, 0, 0));