findChessboardCorners crashing, inconsistent API [patch] (Bug #648)


Added by Gašper Ažman over 14 years ago. Updated over 14 years ago.


Status:Done Start date:
Priority:High Due date:
Assignee:- % Done:

0%

Category:imgproc, video
Target version:-
Affected version: Operating System:
Difficulty: HW Platform:
Pull request:

Description

Hi,

I had a lot of problems getting findChessboardCorners to work. It crashed reproducibly, and even when I did manage to get it to work without crashing the resulting vector was unchanged from the zeroes it contained from the start. The cause of the crash was always a memory fault in std::vector, I'm guessing because it was being used by c code in an ugly way.

Another problem is the API - the found corners are stored in a std::vector, which is incompatible with drawChessboardCorners.

I had a lot more luck using this implementation of the function, which fixes both of these problems:

bool actually_find_chessboard_corners(const cv::Mat& frame, cv::Mat& corners, const cv::Size& size, int flags) {
int count = size.area()*2;
corners.create(count, 1, CV_32FC2);
CvMat _image = frame;
bool ok = cvFindChessboardCorners(&_image, size,
reinterpret_cast<CvPoint2D32f*>(corners.data),
&count, flags ) > 0;
return ok;
}


Associated revisions

Revision 9130d5ba
Added by Vadim Pisarevsky over 14 years ago

put extra check to cv::findChessboardCorners (ticket #648)

Revision 1eb34e06
Added by Andrey Kamaev almost 12 years ago

Merge pull request #648 from cuda-geek:move-gpu-soft-cascade-to-softcascade-module

History

Updated by Vadim Pisarevsky over 14 years ago

as I see it, the only reason why it could happen, is that the output vector is resized to the size "count" after cvFindChessboardCorners() call, and if count is < 0, the negative number is translated to very huge positive number and thus the resize fails.

I put the guard check before calling vector::resize.

if(count >= 0)
corners.resize(count);

hope, it will help.
As for the different interfaces, it's easy to cast vector to Mat. Simply write Mat(corners). The inverse conversion is also possible, but it involves allocation of a new vector and full copy of the data, since STL vectors can not use externally-allocated data. For this reason, in almost every place in OpenCV, where a function takes vector on input, we use Mat argument type instead, because it allows the user to pass either Mat or vector. For output data we have to use vector.

  • Status changed from Open to Done
  • (deleted custom field) set to fixed

Updated by Gašper Ažman over 14 years ago

Thanks for the tip about Mat(corners). I followed up a bit on using the internal storage of vector and it indeed seems as though &vr0 is kosher, although I still find it extremely ugly :).

I also see why it would seem like a good idea to use vectors on output etc. I'll see whether that check does anything tomorrow though.

Thanks and all the best,

Gašper

Also available in: Atom PDF