Search code examples
javaandroidc++opencvconvexity-defects

OpenCV Java convexity defects (Computer Vision)


I have a problem with putting my convexity defects on the frame. To calculate them, I modified c++ source and this is what i archived:

    mConvexityDefectsMatOfInt4 = new MatOfInt4();

    if(contours.size() > 0 && convexHullMatOfInt.rows() > 0)
        Imgproc.convexityDefects(contours.get(0), convexHullMatOfInt,   mConvexityDefectsMatOfInt4);

However, the Imgproc.drawContours(...) method requires that convexityDefects passed to it as a parameters will be ArrayList. I don't know how can I make the conversion. I had also similar problem with convex hulls, but I found out a walkaround:

  convexHullMatOfInt = new MatOfInt();
  convexHullPointArrayList = new ArrayList<Point>();
  convexHullMatOfPoint = new MatOfPoint();
  convexHullMatOfPointArrayList = new ArrayList<MatOfPoint>();

  //Calculate convex hulls
  if(contours.size() > 0)
  {
    Imgproc.convexHull( contours.get(0), convexHullMatOfInt, false );
    for(int j=0; j < convexHullMatOfInt.toList().size(); j++)
      convexHullPointArrayList.add(contours.get(0).toList().get(convexHullMatOfInt.toList().get(j)));
    convexHullMatOfPoint.fromList(convexHullPointArrayList);
    convexHullMatOfPointArrayList.add(convexHullMatOfPoint);   
  }

Similar solution for convexity defects is not working. Does anyone have an idea on how can I solve the problem?

How to convert from MatOfInt4() to ArrayList() to be able to draw convexity defects?


Solution

  • (I myself was struggling so much with convexityDefect that I wanted to kill whoever has written the Java interface for OpenCV!)

    Now the answer:

    As stated in docs, MatOfInt4 is basically a 4-element integer array containing the following information:

    start_index
    end_index
    farthest_pt_index
    fixpt_depth
    

    You can use the following to convert mConvexityDefectsMatOfInt4 to a list of integers:

    List<Integer> cdList = mConvexityDefectsMatOfInt4.toList();
    

    Now, each 4 consecutive elements in cdList holds the info stated above:

    cdList 0 : 23    
    cdList 1 : 30      
    cdList 2 : 26    
    cdList 3 : 18101
    -----------------
    cdList 4 : 30
    cdList 5 : 44
    cdList 6 : 33
    cdList 7 : 43738
    

    So, for example if you want to draw only the farthest point of each concavity, you can simply use the third index of each 4 elements. In this case: 26, 33, ...

    Hope it helps.