简体   繁体   中英

Passing OpenCV contours from a JNI C++ function to Java in Android

What is the best way to pass OpenCV vector< std::vector<Point > > contours from a JNI C++ function to Java in Android? My current approach is to use arrays of doubles but this is very inefficient. Is there a way to use pointers maybe?

Well, you can create a class at Java side equivalent to vector< std::vector<Point > > in C++ side. Then, write a serializer function in C++ and deserailizer method in Java.

Your serializer can be a String composed of double values which are seperated by , and ; , which can be deserialized easliy in Java.

In this way, instead of sending multiple arrays you can sen just one string. You need to be careful with the precision of double when converting it to double and converting it back.

Here's an efficient way to access contours with the wrapper from the JavaCPP Presets for OpenCV :

import org.bytedeco.javacpp.indexer.*;
import static org.bytedeco.javacpp.opencv_core.*;
import static org.bytedeco.javacpp.opencv_imgproc.*;
import static org.bytedeco.javacpp.opencv_highgui.*;

public class Contours {
    public static void main(String[] args) {
        Mat grayscaleImage = imread("lena.png", CV_LOAD_IMAGE_GRAYSCALE);
        Mat binarizedImage = new Mat();
        MatVector contours = new MatVector();
        threshold(grayscaleImage, binarizedImage, 128, 255, THRESH_BINARY);
        findContours(binarizedImage, contours, RETR_LIST, CHAIN_APPROX_NONE);
        int contoursSize = (int)contours.size();
        System.out.println("size = " + contoursSize);
        for (int contourIdx = 0; contourIdx < contoursSize; contourIdx++) {
            // compute center
            float x = 0, y = 0;
            Mat contour = contours.get(contourIdx);
            IntIndexer points = contour.createIndexer(false);
            int pointsSize = contour.rows();
            for (int pointIdx = 0; pointIdx < pointsSize; pointIdx++) {
                x += points.get(pointIdx, 0);
                y += points.get(pointIdx, 1);
            }
            System.out.println("center = (" + x / pointsSize + ", " + y / pointsSize + ")");
        }
    }
}

For simplicity, I'm using Java SE, but we can do the same thing on Android.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM