Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible native stack corruption in C++ API's findContours(Mat, Mat, Mat, int, int, Point) #34

Closed
chile12 opened this issue Aug 29, 2014 · 4 comments

Comments

@chile12
Copy link

chile12 commented Aug 29, 2014

Hello

I encountered a SIGSEGV when executing my javacv based heuristic in a loop.
After a lot of searching, reading and experimenting I found the source has to be the findContoures method (org.bytedeco.javacpp.opencv_imgproc.findContours).
The only workaround I came up with was using the C implementation of this method.
SIGSEGV disappeared instantly.

Let me know if you need my code example for further investigation.

Greetings.

PS.: I#m using v. 0.9

@saudet
Copy link
Member

saudet commented Aug 29, 2014

Could you provide a few lines of code to reproduce that issue? Thanks!

@chile12
Copy link
Author

chile12 commented Aug 29, 2014

All right:

This is a short extract of my code which is executed constantly in a loop.
In the second loop, the first allocation of an opencv object raises the SIGSEGV:

08-28 18:19:25.671: I/DEBUG(3741): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad

public static  List<Rect> getBoundingBoxesOfContoures(Mat bitImage, BackGroundShade shade, int blockSize, int weightConstant)  throws FrameNotFoundException
{
    Mat contourImage = bitImage;
    List<Rect> boundingBoxes = new ArrayList<Rect>();
    MatVector contours = new MatVector();
    if(shade == BackGroundShade.Dark || shade == BackGroundShade.Undef)
    {
        adaptiveThreshold(bitImage, contourImage, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, blockSize, weightConstant);
        contours.put(ImageStatics.GetContoursOfImage(contourImage));
        boundingBoxes.addAll(extractRectanglesFromMatVector(contours));
    }
    if(shade == BackGroundShade.Bright || shade == BackGroundShade.Undef)
    {
        adaptiveThreshold(bitImage, contourImage, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, blockSize, weightConstant);
        contours.put(ImageStatics.GetContoursOfImage(contourImage));
        boundingBoxes.addAll(extractRectanglesFromMatVector(contours));
    }
    return boundingBoxes;
}
public static MatVector GetContoursOfImage(Mat input)
{
    MatVector contours = new MatVector();
    findContours(input, contours, new Mat(), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, new Point(0,0));

    return contours;
}

public static List<Rect> extractRectanglesFromMatVector(MatVector contours) throws FrameNotFoundException {
    List<Rect> outout = new ArrayList<Rect>();
    for (int i =0; i < contours.size(); i++)
    {
        Rect zw = boundingRect(contours.get(i));
        if(zw != null)
            outout.add(zw);
    }
    return outout;
}

My current work araound looks like this:

public static List<CvRect> GetContoursOfImage(Mat input)
{
    CvSeq contours = new CvSeq();

    cvFindContours(input.asCvMat(), CvMemStorage.create(), contours, Loader.sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

    List<CvRect> rects = new ArrayList<CvRect>();
    CvSeq zw = new CvSeq();
    if(contours!=null) {
        for (zw = contours; zw != null; zw = zw.h_next()) { 
            rects.add(cvBoundingRect(zw,0));
        }

    }   
    return rects;
}

I'd like to see this without the C-work-around :)

Thank you.

@saudet
Copy link
Member

saudet commented Aug 29, 2014

Your issue might have something to do with your put() call. There isn't a MatVector.put(MatVector) method, so what gets called is MatVector.put(Pointer) and that uses memcpy(), which is probably not a good idea for a non-PODS class...

@chile12
Copy link
Author

chile12 commented Aug 31, 2014

Seems kinda obvious in hindsight, damn it.

Thanks.

@chile12 chile12 closed this as completed Aug 31, 2014
saudet added a commit to bytedeco/javacpp that referenced this issue Oct 5, 2014
…when integer values are larger than 32 bits

 * Have the `Parser` produce `@Name("operator=") ... put(... )` methods for standard C++ containers, avoiding mistaken calls to `Pointer.put(Pointer)` ([issue javacv:34](bytedeco/javacv#34))
 * Let the `Parser` apply `Info.skip` in the case of macros as well
 * Remove warning log messages when using the `@Raw` annotation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants