findChessboardCorners crashing, inconsistent API [patch] (Bug #648)
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
put extra check to cv::findChessboardCorners (ticket #648)
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