Ask Your Question

Revision history [back]

Android: Adding Values to a MatOfInt4

I am new to OpenCV, and am working with OpenCV4Android. It is frustrating because 99% of the examples online and all of the documentation are for C++ and they don't simply translate over in a lot of cases.

I am working on a rectangle detection algorithm using the HoughLinesP algorithm. Right now, I run the algorithm and get a MatOfInt4 object (called lines) which has the detected line segments as an array of four doubles describing the endpoints of the line segment. I pass these to a method which extends these line segments to the borders of the screen. The problem is the algorithm finds more than 4 lines. It will usually find 6-10, where several are duplicates that essentially retrace a known line.

So I have a method where I WANT to create a MatOfInt4 object of JUST the unique lines (called uniqueLines). So I scan through each column in lines and compare it to all of the entries in uniqueLines. If the endpoints are identical (within a threshold), it should reject the line, but if the line being inspected doesn't match any other, it is added to uniqueLines. When the method finishes, I return the uniqueLines object.

private MatOfInt4 extendAndFilterLines(Mat imageMat, MatOfInt4 lines) {
    MatOfInt4 uniqueLines = new MatOfInt4();
    uniqueLines.create(0, 4, uniqueLines.type());
    int count = uniqueLines.cols();

    int numUnique = 0;
    int threshold = 10;

    for (int i = 0; i < lines.cols(); i++) {

        // Logic erased here extending the lines

        // Iterate through all saved lines. If not unique, discard.
        for (int j = 0; j < numUnique; j++) {
            double[] v = uniqueLines.get(0, j);

            double dx1, dy1, dx2, dy2;
            dx1 = Math.abs(v[0] - val[0]);
            dy1 = Math.abs(v[1] - val[1]);
            dx2 = Math.abs(v[2] - val[2]);
            dy2 = Math.abs(v[3] - val[3]);

            Log.i(LOG_TAG, "Deltas: " + (int) dx1 + " " + (int) dy1 + " " + (int) dx2 + " " + (int) dy2);

            if ( dx1 < threshold && dy1 < threshold && dx2 < threshold && dy2 < threshold ) {
                unique = false;
                break;
            }
        }

        if (unique) {
            Log.i(LOG_TAG, "Unique Line: " + " (" + (int) val[0] + ", " + (int) val[1] + "), ("
                    + (int) val[2] + ", " + (int) val[3] + ") angle " + (int) angle);
            uniqueLines.put(0, numUnique, val);
            numUnique++;
        }
    }

    Log.i(LOG_TAG, numUnique + " unique lines found.");
    return uniqueLines;
}

The problem is that when I try to put val into the uniqueLines object, it doesn't actually get placed there, so when on the next iteration I call uniqueLines.get(0, j) and try to reference the data that was supposed to have been placed in there, I get a null pointer exception.

I also tried converting val into a Mat object and using the push_back method, but it only adds the first unique line and subsequent calls to push_back do absolutely nothing.

Any assistance would be greatly appreciated.