Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion between OpenCv4Android and C++ data types

Tags:

android

opencv

I am trying to write some applications using OpenCv4Android for Android devices. Earlier, i was using Android NDK and C++ native codes. But that technique wasn't much lucid. So i switched over to latest Java API coming along with OpenCv 2.4.4 version.

I was able to write simple programs and run samples. But, while i tried to write some codes for advanced problems like - Model POSE estimation, Camera calibration routines etc, I came across this very strange confusion. Some of the data types whose names are very intuitive in C++ API doesn't really fit in in their Java counterpart. Hence, I am facing terrible difficulty to port my functionality from C++ to Java. I am facing utter confusion in these functions

  • Point2f (in C++ ) - MatOfPoint2f (in Java)
  • Point3f (in C++) - MatOfPoint3f (in Java)
  • Point2 (in Java)
  • Point3 (in Java)

Please help me understand the terms used in OpenCv Java and its analogy with C++.

Also, please suggest me some reference where, clear and crisp description of these terms are given (i tried watching the help provided along, but it didn't help me much, as it was somewhat similar for both C++ and Java).

like image 936
Utkarsh Mankad Avatar asked Apr 09 '13 04:04

Utkarsh Mankad


1 Answers

Quoting Andrey Pavlenko:

MatOfXxx classes (e.g. MatOfPoint) were introduced to avoid redundant copying of intermediate data between Java and native memory. E.g. you can get some large set of Points as the result of one OpenCV function and then pass it to another one.

In C++ we use std::vector for this. But use of ArrayList in Java caused copying all the Points data from native OpenCV level to Java when returning these Points and copying them back when calling the next OpenCV function using them. So for the sake of efficiency we switched to use of MatOfPoint class in such cases that is a kind of Mat of 1n or n1 dimensions that keeps a Point in each element (i.e. of type CV_32SC2 or CV_64FC2).

As you may know, Mat keeps all the data on native level, so such objects can be passed between OpenCV calls without data copying. But if in your Java code at some point you need direct access to actual Points data there are toArray() and fromArray methods to explicit transfer data to/from Java.

For example, to create a MatOfPoint2f containing the points corresponding to ones from existing MatOfKeyPoint you need:

  • load KeyPoints to Java via MatOfKeyPoint.toArray()
  • iterate through KeyPoint[] and create a corresponding Point[] (all of cv::Point, cv::Point2f and cv::Point2d are represented as org.opencv.core.Point in Java)
  • use MatOfPoint2f.fromArray() or c-tor MatOfPoint2f(Point...pa)to put your Points to native level

As for the C++ vs Java types correspondence:

vector<Point>    : MatOfPoint
vector<Point2f>  : MatOfPoint2f
vector<Point3i>  : MatOfPoint3
vector<Point3f>  : MatOfPoint3f
vector<KeyPoint> : MatOfKeyPoint
vector<DMatch>   : MatOfDMatch
vector<Rect>     : MatOfRect
vector<uchar>    : MatOfByte
vector<char>     : MatOfByte
vector<int>      : MatOfInt
vector<float>    : MatOfFloat
vector<double>   : MatOfDouble
vector<Vec4i>    : MatOfInt4
vector<Vec4f>    : MatOfFloat4
like image 63
Rui Marques Avatar answered Oct 15 '22 21:10

Rui Marques