Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

openCV java code pass Point object to native code(C++)?

I'm currently developing an openCV app on Android. Untill now my app is all written in Java, however there's one function that takes MatOfPoint object as a parameter that I want to implement in native code(C++). From openCV Tutorial 2 I know how to pass Mat object to native code method, but what about objects of other class, like Point and MatOfPoint? Any sample code that shows how to do it?

Thanks.

like image 680
eaglesky Avatar asked Mar 11 '14 07:03

eaglesky


1 Answers

For a point i recomend just passing x and y as doubles. For MatOfPoints and others:

OpenCV comes with converters that store different kind of stuff in a Mat.

There is the converter on the java side, that is part of the opencv-android-sdk org.opencv.utils.Converters

There is also a C++ converter i found in the opencv repo, but the header is not included in the opencv-android-sdk, and i couldn't get it working with just adding the header so i copied the converters.h and converters.cpp to my jni folder and corrected the imports to point to the right place (but this might not be necessary).

https://github.com/Itseez/opencv/blob/master/modules/java/generator/src/cpp/converters.cpp

This converters can be used to pass MatOfPoint or List and a lot more to your native code, where you have to convert it again to a c++ type (c++ equivalent of MatOfPoint is std::vector< cv::Point >; equivalent of List is std::vector< std::vector< cv::Point > >)

With this converters you can "convert" a MatOfPoint to a Mat and back using vector_Point_to_Mat or Mat_to_vector_Point (returns a List but with MatOfPoint.fromList you get a MatOfPoint from that)

Here is an example how to pass List to native level and a MatOfPoint back.

Java code:

public class YourJavaWrapper {

    static {
        System.loadLibrary("yourlibrary");
    }

    public static MatOfPoint findMostFencyMatOfPoints(List<MatOfPoint> contours){

        List<Mat> contoursTmp = new ArrayList<Mat>(contours.size());
        Mat inputMat = Converters.vector_vector_Point_to_Mat(contours, contoursTmp);
        Mat outputMat = new Mat();

        findMostFencyMatOfPoints(inputMat.nativeObj, outputMat.nativeObj);

        List<Point> pointsTmp = new ArrayList<Point>();
        Converters.Mat_to_vector_Point(outputMat, pointsTmp);
        MatOfPoint matOfInterest = new MatOfPoint();
        matOfInterest.fromList(pointsTmp);
        outputMat.release();

        return matOfInterest;
    }

    private static native void findMostFencyMatOfPoints(long inputMatAddress, long outPutMatAddress);

}

C++ code:

using namespace std;
using namespace cv;

extern "C" JNIEXPORT void JNICALL Java_org_example_yourpackage_YourJavaWrapper_findMostFencyMatOfPoints(JNIEnv*, jobject, jlong inputMatAddress, jlong outPutMatAddress)
{
    cv::Mat& vectorVectorPointMat = *(cv::Mat*) inputMatAddress;
    std::vector< std::vector< cv::Point > > contours;
    Mat_to_vector_vector_Point(vectorVectorPointMat, contours);
    std::vector<cv::Point> fencyVectorOfPoints = findMostFencyVectorOfPoint(contours);
    cv::Mat& largestSquareMat = *(cv::Mat*) outPutMatAddress;
    vector_Point_to_Mat(fencyVectorOfPoints, outPutMatAddress);
}

in this example findMostFencyVectorOfPoint is your custom native function

like image 101
Zarokka Avatar answered Oct 18 '22 04:10

Zarokka