将 OpenCV 轮廓从 JNI C++ 函数传递到 Android 中的 Java



OpenCV vector< std::vector<Point > > contours从JNI C++函数传递到Android中的Java的最佳方法是什么?我目前的方法是使用双精度数组,但这非常低效。有没有办法使用指针?

好吧,你可以在 Java 端创建一个类,相当于C++端的 vector< std::vector<Point > >。然后,在 C++ 中编写序列化程序函数,在 Java 中编写 deserailizer 方法。

你的序列化程序可以是一个由双精度值组成的String,这些值由 ,; 分隔,可以在 Java 中轻松反序列化。

这样,您可以只发送一个字符串,而不是发送多个数组。在将其转换为双精度并将其转换回来时,您需要小心双精度。

以下是使用OpenCV的JavaCPP预设中的包装器访问轮廓的有效方法:

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 + ")");
        }
    }
}

为了简单起见,我使用的是Java SE,但我们可以在Android上做同样的事情。

最新更新