Ask Your Question

clytemnestra13's profile - activity

2017-06-16 02:58:32 -0600 commented question Not all convexity defects are being found

WOW IT WORKED! Thanks a billion! Any idea what I was doing wrong? The java data structures for defects are a pain to figure out.

2017-06-12 04:08:13 -0600 commented question Not all convexity defects are being found

Yes, I get arrayindexoutofboundsexception if I do that.

2017-06-12 03:57:21 -0600 received badge  Enthusiast
2017-06-09 07:01:31 -0600 commented question Not all convexity defects are being found

defect.startPoint is already a point from the contour array of points. The problem is I don't get all of the defects from the image, the defects array is just too small.

2017-06-08 08:49:21 -0600 commented question Not all convexity defects are being found

Mind helping when you have time? I still haven't managed to solve this.

2017-06-03 18:04:16 -0600 commented question Not all convexity defects are being found

I have added the SkinDetector class code that will create the binary image. Also the drawer class that will show you how I output different stuff.

2017-06-01 05:32:52 -0600 commented question Not all convexity defects are being found

Ok, I changed them. Now if anyone could give me some pointers at what I'm doing wrong...

2017-05-31 08:48:05 -0600 asked a question Not all convexity defects are being found

I wrote some code to detect convexity defects from a picture. I use opencv320 (tried 240 and got the exact same issue) and the code is Java.

image description

And the result is always the same, it stops at a point and I don't understand why: image description

As you see, I drew the bounding rectangle, the contour, the convex hull and when I want to calculate the convexity defects they are calculated only up until the ring finger starts.

public class Recognition {

    protected String whichHand = "left";
    public ArrayList<MatOfPoint> contours = new ArrayList<>();
    public MatOfPoint largestContour;
    public MatOfInt convexHull = new MatOfInt();
    protected Mat originalImage;
    public int largestContourIndex = -1;
    public MatOfInt4 convexityDefects = new MatOfInt4();
    public ArrayList<Defect> relevantDefects = new ArrayList<Defect>();

    public Recognition(Mat originalImage) {

        this.originalImage = originalImage;
    }


    public Recognition flip() {
        if (whichHand != "left")
            Core.flip(originalImage, originalImage, 1);

        return this;
    }

    public Recognition getContours() {
        Imgproc.findContours(originalImage, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));

        return this;
    }

    public Recognition getLargestContour() {


        double largestArea = 0;
        int contourNumber = contours.size();

        for (int i = 0; i < contourNumber; i++) {
            //double a=contourArea( hull[i],false);  //  surface
            double contourArea = Imgproc.contourArea(contours.get(i));
            if (contourArea > largestArea) {
                largestArea = contourArea;
                largestContourIndex = i;
            }

        }

        largestContour = contours.get(largestContourIndex);

        return this;
    }

    public Recognition getConvexHull() {

        Imgproc.convexHull(largestContour, convexHull);

        return this;
    }


    public Recognition getConvexityDefects() {

        Imgproc.convexityDefects(largestContour, convexHull, convexityDefects);

        int convexityDefectsList[] = convexityDefects.toArray();
        int convexityDefectsSize = convexityDefectsList.length;



        Point contourArray[] = largestContour.toArray();

        for (int d = 0; d < convexityDefectsSize; d += 4) {
            Point startPoint = contourArray[d];
            Point endPoint = contourArray[d + 1];
            Point depthPoint = contourArray[d + 2];

            double depth = convexityDefectsList[d + 3] / 256;

            Defect defect = new Defect();
            defect.startPoint = startPoint;
            defect.endPoint = endPoint;
            defect.depthPoint = depthPoint;
            defect.depth = depth;

            relevantDefects.add(defect);

        }


        return this;
    }

}

I think the problem is that I am getting way too few defects, around 20-30, but the Java function has really strange output when compared with the c++ one, it puts all the defects info in groups of 4 in the same array, really strange, so I've made an object to store it better.

I think I calculate the contour and hull properly, because you can see in the image that it's displayed fully.

This is the code I use, drawer is just another class that draws the specific points on the image, if you want I can provide it, too. I load the image, detect skin from the binary version, get the largest contour, get the hull and try to get the convexity defects.

Mat imagemat = Imgcodecs.imread("src/hsr/util/D1.png");
Mat skinMat = SkinDetector.detectSkin(imagemat);
Recognition recognition = new Recognition(skinMat);
Drawer drawer = new Drawer();
recognition.flip().getContours().getLargestContour();
Mat contourMat = Mat.zeros(skinMat.size(), CvType.CV_8UC3);
recognition.getConvexHull().getConvexityDefects();
drawer.showBiggestContour(contourMat,recognition.contours,recognition.largestContourIndex);
drawer.showHull(contourMat,recognition.convexHull,recognition.largestContour);
drawer.showRotatedBoundingRectangle(recognition.largestContour,contourMat);
drawer.drawDefects(contourMat,recognition.relevantDefects);
Imgcodecs.imwrite("asd.png",contourMat);

Skindetector class

public class SkinDetector {

    public static Mat detectSkin(Mat input) {


        //test
//        int Y_MIN = 0;
//        int Y_MAX = 255;
//        int Cr_MIN = 135;
//        int Cr_MAX = 180;
//        int Cb_MIN = 85;
//        int ...
(more)