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?
Asked
Active
Viewed 675 times
0

Jaime Ivan Cervantes
- 3,579
- 1
- 40
- 38
-
There are no pointers in java. You can store a pointer value into a java long but that only helps to keep the reference. – Fildor Dec 02 '14 at 06:14
-
1Maybe this answer helps you http://stackoverflow.com/a/23116736/2455351 (It's done for passing a vector
) – migue02 Dec 02 '14 at 07:51 -
1FYI, we can directly access that type in Java using [JavaCPP](https://github.com/bytedeco/javacpp/): http://bytedeco.org/javacpp-presets/opencv/apidocs/org/bytedeco/javacpp/class-use/opencv_core.PointVectorVector.html – Samuel Audet Dec 06 '14 at 08:13
-
@SamuelAudet your comment is closer to what I was looking for, but I've never used JavaCPP. If you post an answer where you elaborate more on this, I will select it. – Jaime Ivan Cervantes Dec 07 '14 at 18:53
2 Answers
2
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.

guneykayim
- 5,210
- 2
- 29
- 61
1
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.

Samuel Audet
- 4,964
- 1
- 26
- 33