wxrw
wxrw

Reputation: 97

Rewrite OpenCV method from Java to C++

Could anyone tell me how does this piece of code looks like in C++ ? I'm really confused about java and it's representation of OpenCV.

public static MatOfPoint convexHull(MatOfPoint contour) {
    MatOfInt indexes = new MatOfInt();
    Imgproc.convexHull(contour, indexes);
    Point[] convexPoint = new Point[indexes.rows()];

    double x, y;
    int index;
    for (int i = 0; i < indexes.rows(); i++) {
       index = (int) indexes.get(i, 0)[0];
       x = contour.get(index, 0)[0];
       y = contour.get(index, 0)[1];
       convexPoint[i] = new Point(x, y);
    }

  return new MatOfPoint(convexPoint);
}

What I got so far is :

vector< Point > convexHull(vector< Point> & contour) {
  vector<int> indexes;
  convexHull(contour, indexes);
  Point[] convexPoint = new Point[indexes.size()];

  double x, y;
  int index;
  for (size_t i = 0; i < indexes.size(); i++) {
     //I really don't understant what's going on here  
  }
}

Also could anyone explain me please the body of for-loop of that java code ?

Upvotes: 0

Views: 298

Answers (2)

Soheyb Kadi
Soheyb Kadi

Reputation: 186

First of all, I don't get why you want to convert a java code to c++ when that already exist. Looking at your posted code (if this is copied from somewhere, it will be very helpful to post link here)

public static MatOfPoint convexHull(MatOfPoint contour) {
    MatOfInt indexes = new MatOfInt();
    Imgproc.convexHull(contour, indexes);
    Point[] convexPoint = new Point[indexes.rows()];

    double x, y;
    int index;
    for (int i = 0; i < indexes.rows(); i++) {
       index = (int) indexes.get(i, 0)[0];
       x = contour.get(index, 0)[0];
       y = contour.get(index, 0)[1];
       convexPoint[i] = new Point(x, y);
    }

  return new MatOfPoint(convexPoint);
}

That code is calling opencv Imgproc.convexHull(contour,indexes). It passes MatOfInt which means you will get indexes of points. Now if you look carefully at return value of the function, you can it is of type MatOfPoint, and that inside of the for loop, we are building the return object from point indexes. So the loop is just to convert from indexes to actual points. This is to describe what's happening in that code. But what makes all this strange is that opencv C++ (Not sure if opencv/java has this) has already the function to return actual points. You can check opencv official documentation on convexHull function here

Opencv c++ convexHull function signature is:

void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true )

And the parameters description is:

Parameters:
points – Input 2D point set, stored in std::vector or Mat. hull – Output convex hull. It is either an integer vector of indices or vector of points. In the first case, the hull elements are 0-based indices of the convex hull points in the original array (since the set of convex hull points is a subset of the original point set). In the second case, hull elements are the convex hull points themselves.
clockwise – Orientation flag. If it is true, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise. The assumed coordinate system has its X axis pointing to the right, and its Y axis pointing upwards. orientation – Convex hull orientation parameter in the old API, CV_CLOCKWISE or CV_COUNTERCLOCKWISE. returnPoints – Operation flag. In case of a matrix, when the flag is true, the function returns convex hull points. Otherwise, it returns indices of the convex hull points. When the output array is std::vector, the flag is ignored, and the output depends on the type of the vector: std::vector implies returnPoints=true, std::vector implies returnPoints=false.

As you can see from description of the parameters, if you pass hull as a vector of integers, you get back indexes. But if you pass a vector of points, you get back actual points rather than their indices. That's exactly what your posted function is doing. So rather than converting to c++, just use opencv c++ convexHull function directly by passing a vector of points.

Upvotes: 1

Dan Mašek
Dan Mašek

Reputation: 19041

The loop populates the convexPoint array with points from contour, according to the indices returned by Imgproc.convexHull.

I'm not sure about Java, but in with the C++ API it's rather pointless, since cv::convexHull will happily do that for you when the output argument is std::vector<cv::Point>.

Then function then becomes

std::vector<cv::Point> convexHull(std::vector<cv::Point> const& contour)
{
    std::vector<cv::Point> result;
    cv::convexHull(contour, result);
    return result;
}

and it becomes somewhat questionable whether you even need it.

Upvotes: 2

Related Questions