Ask Your Question
0

Problem using SimpleBlobDetector::detect

asked 2018-04-11 10:39:21 -0500

MarcoG gravatar image

updated 2018-04-11 10:48:48 -0500

Hi there, I've got a function which takes two Mat as parameters, const imgIn and ImgOut. ImgIn is a thresholded binary (either 0xffffffff or 0xff000000) image with two with blobs in them (I threshold two neon green balls that I use as markers). I want to use SimpleBlobDetector as demonstrated there : https://www.learnopencv.com/blob-dete... . The img_with_keypoints being my imgOut so I can display in other part of my program. No matter what I tried so far, I keep running into an unhandled exception at function call myDetector->detect(imgIn, keypoints) even if both parameters seems valid when debugging. The imgIn comes from my webcam and start as a QImage (AARRGGBB). I successfully translate it in Mat and use it in cv::erode function... Does anyone have any clue on what could cause that?

Here is my code, which is mainly copied from the tutorial.

void VR_BlobProcess::process(const Mat & imgIn, Mat & imgOut)
{
    // Setup SimpleBlobDetector parameters.
    SimpleBlobDetector::Params params;

    params.filterByArea = true;
    params.minArea = 100;
    params.maxArea = 1000;
    params.filterByColor = true;
    params.blobColor = 255;

#if CV_MAJOR_VERSION < 3   // If you are using OpenCV 2

    // Set up detector with params
    SimpleBlobDetector detector(params);

    // You can use the detector this way
    // detector.detect( im, keypoints);

#else

    // Set up detector with params
    Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);

    // SimpleBlobDetector::create creates a smart pointer. 
    // So you need to use arrow ( ->) instead of dot ( . )
    // detector->detect( im, keypoints);

#endif
    std::vector<cv::KeyPoint> keypoints;

    detector->detect(imgIn, keypoints);

    // Draw detected blobs as red circles.
    // DrawMatchesFlags::DRAW_RICH_KEYPOINTS flag ensures the size of the circle corresponds to the size of blob
    Mat im_with_keypoints;
    drawKeypoints(imgIn, keypoints, im_with_keypoints, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    imgOut = im_with_keypoints;
}

EDIT: as asked, here is also the function used to convert QImage to Mat:

void VR_FrameGrabberProcess::process(const Mat &imgIn, Mat &imgOut)
{
    imgOut = qimage_to_mat_ref(currentFrame, QImage::Format_ARGB32);
}

// Pris sur http://qtandopencv.blogspot.ca/2013/08/how-to-convert-between-cvmat-and-qimage.html
Mat VR_FrameGrabberProcess::qimage_to_mat_ref(QImage &img, int format)
{
    return cv::Mat(img.height(), img.width(),format, img.bits(), img.bytesPerLine());
}

thank you for your time.

edit retag flag offensive close merge delete

Comments

maybe you need to add the code for yout qtimage -> Mat conversion, too.

berak gravatar imageberak ( 2018-04-11 10:42:32 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2018-04-11 10:52:14 -0500

berak gravatar image

updated 2018-04-11 10:53:56 -0500

the problem is here:

return cv::Mat(img.height(), img.width(),format, img.bits(), img.bytesPerLine());

you're taking a shallow copy of the data pointer (img.bits()) here, it will be invalid, once you leave that callback function.

remedy: add a clone() as in:

return cv::Mat(img.height(), img.width(),format, img.bits(), img.bytesPerLine()).clone();
edit flag offensive delete link more

Comments

Thank you for your answer. I changed it the way you told but I still run in the same exception. What I don't understand is that I use my input image in three process before the detection. The way my program is designed is an ImageProcessor that call all my process and those process are all linked in a way that the ImgOut of one is the imgIn of the other.

MarcoG gravatar imageMarcoG ( 2018-04-11 11:09:35 -0500 )edit

please lookup "undefined behaviour". (that's what your original code was doing)

berak gravatar imageberak ( 2018-04-11 11:12:17 -0500 )edit

Will do, thanks.

MarcoG gravatar imageMarcoG ( 2018-04-11 11:15:32 -0500 )edit

Hi, me again, I figured out what my problem was. It's the format I pass in the constructor. I use a Qt::QImage constant and I needed to use, obviously, a cv constant. So I simply passed cv::CV_8UC4 instead and it worked. Thanks again.

MarcoG gravatar imageMarcoG ( 2018-04-13 13:30:42 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2018-04-11 10:39:21 -0500

Seen: 370 times

Last updated: Apr 11 '18