Search code examples
javac++opencvjavacvaffinetransform

Passing Point2f [] as arguments for getAffineTransform() in Javacv


I am trying to implement the face alignment implementation C++ bit found here in java using javacv but I am stuck at how to pass

point2f[] as point2f in getAffineTransform().

This is what I have been able to come up with;

    //face alignment begin
Point2f[] srcTri = new Point2f[3];
Point2f[] dstTri = new Point2f[3];

Mat src_mat= new Mat(orig);
Mat dst_mat= new Mat(input);
Mat warp_mat = new Mat( 2, 3, CV_32FC1);

//Set the dst image the same type and size as src
Mat warp_dst = new Mat(src_mat.rows(), src_mat.cols(), src_mat.type());

//Set your 3 points to calculate the  Affine Transform
srcTri[0] = new Point2f((float)landmarks[5*2], (float)landmarks[5*2+1]);
srcTri[1] = new Point2f((float)landmarks[6*2], (float)landmarks[6*2+1]);
srcTri[2] = new Point2f((float)landmarks[0*2], (float)landmarks[0*2+1]);

dstTri[0] = new Point2f((float)landmarks[5*2], (float)landmarks[5*2+1]);
dstTri[1] = new Point2f((float)landmarks[6*2], (float)landmarks[6*2+1]);
dstTri[2] = new Point2f((float)landmarks[0*2], (float)landmarks[0*2+1]);

//Get the Affine Transform 
warp_mat = getAffineTransform( srcTri, dstTri ); //This is where I have problems. getAffineTransform() expects Point2f but I have Point2f[]

//Apply the Affine Transform just found to the src image
warpAffine(src_mat, warp_dst, warp_mat, warp_dst.size()); 

//show images
imshow("src", src_mat);
imshow("dst", dst_mat);
imshow("warp_dst", warp_dst);
waitKey(0);

//face alignment end

Someone please show me how I should pass srcTri and dstTri as Point2f to getAffineTransform() or how to convert Point2f[] to Point2f. Is it even possible to do so? How can get the landmarks into a Point2f that can be accepted as an argument in getAfflineTransform() ?

I will gladly appreciate your help on how to navigate here.


Solution

  • I believe here is the answer: https://groups.google.com/d/msg/javacv/dbWTNCHFyeg/Q6k59GPavgsJ:

    Point2f is a Pointer, which works like a native array: http://bytedeco.org/javacpp-presets/opencv/apidocs/org/bytedeco/javacpp/opencv_core.Point2f.html

    And we can do things like that with a Pointer to access the elements of a native array: http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/Pointer.html#position-int-

    Check the README file for an example with CvPoint: https://github.com/bytedeco/javacv#sample-usage Now do the same thing, but with Point2f.

    So your code should be modified like this:

    Point2f srcTri = new Point2f(3);
    Point2f dstTri = new Point2f(3);
    
    // ...
    
    srcTri.position(0).x((float)landmarks[5*2]).y((float)landmarks[5*2+1]);
    srcTri.position(1).x((float)landmarks[6*2]).y((float)landmarks[6*2+1]);
    srcTri.position(2).x((float)landmarks[0*2]).y((float)landmarks[0*2+1]);
    // and do the same for dstTri
    
    warp_mat = getAffineTransform( srcTri.position(0), dstTri.position(0) );