Calibration from Images results in 0 Successes
I try to calibrate the Camera of a Smartphone with a console application because the speed of the Android example is very slow and It is hard to make proper Images.
The Console Application is inspired by a Book I found: OpenCV 2 Computer Vision: Application Programming Cookbook
Instead of a Chessboard like mentioned in the Book I take the Circle Grid from openCV which can be found in the "data" Folder.
Unfortunately when I use the "addChessboardPoints" Method I get the result of 0 successes and no Points are added into my Calibration. Here the Code:
int Calibrator::addChessboardPoints(const std::vector<std::string>& fileList, cv::Size& boardSize){
double onePerc = fileList.size() / 100.0f;
std::vector<cv::Point2f> imageCorners;
std::vector<cv::Point3f> objectCorners;
calcBoardCornerPositions(boardSize, 13.40, objectCorners, ASYMCIRCLE);
cv::Mat image;
int successes = 0;
for(int i = 0; i < fileList.size(); i++){
double state = i+1.0f;
double progress = state / onePerc;
image = cv::imread(fileList[i], 0);
bool found = cv::findCirclesGrid(image, boardSize, imageCorners, cv::CALIB_CV_ASYMMETRIC_GRID);
if(!found){
std::cout << "Progres: " << progress << "%" << std::endl;
continue;
}
cv::cornerSubPix(image, imageCorners, cv::Size(5,5), cv::Size(-1,-1),
cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 30, 0.1));
if(imageCorners.size() == boardSize.area()){
addPoints(imageCorners, objectCorners);
successes++;
}
std::cout << "Progress: " << progress << "%" << std::endl;
}
return successes;
}
The Images I took with my Camera can be looked up here. The boardSize
used here is cv::Size(11,4)
Does anyone know, what I did wrong?
UPDATE corrected BoardSize and findCirclesGrid flag. Problem still occurs.
UPDATE added calcBoardCornerPositions and usage in addChessboardPoints
void Calibrator::calcBoardCornerPositions(cv::Size boardSize, float squareSize, std::vector<cv::Point3f>& corners, PatternType flag){
//BoardSize is 11,4
switch(flag){
case CHESSBOARD:
case CIRCLEGRID:
for(int i = 0; i < boardSize.height; ++i)
for(int j = 0; j < boardSize.width; ++j)
corners.push_back(cv::Point3f(j*squareSize, i*squareSize, 0));
break;
case ASYMCIRCLE:
for(int i = 0; i < boardSize.height; ++i)
for(int j = 0; j < boardSize.width; ++i)
corners.push_back(cv::Point3f((2*j + i % 2) * squareSize, i*squareSize, 0));
break;
default:
break;
}
}
It is written on the images:
"this is a 11x4 OpenCV assymetric circles' grid"
.I also noticed this a couple of minutes ago (shame on me!) But when I change the boardSize I don't get another Result :/. I also changed the flag to
cv::CALIB_CB_ASYMMETRIC_GRID
But still with(11,4)
and(4,11)
I still get 0 successes Could it be, that my Images are not good?for an asymmetric grid, you need a different objectCorners pattern, see here (calcBoardCornerPositions())
ok, I will implement that method now, but one Question left, what should I put there as squareSize? I printed the circleGrid from the Docs on a DINA4 Paper.
Measure them with a ruler or a caliper should do the trick.
Ok, was not sure with that! And Unit of Measurement? mm would be okay am I right?
Yes 'mm' is fine.
unfortunately I get an Error now at this Line
corners.push_back(cv::Point3f((2*j + i % 2) * squareSize, i*squareSize, 0));
the Error issignal SIGKILL
. The last Task in the Thread List is this:template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {}
can you post your code? EDIT: Do you clear
vector<cv::Point3f> corners
outside of your function?No I don't clear it anywhere. It is just filled once and is never touched after that. The reference Points to objectCorners. Also the Error occurs with the first Iteration of the code.
Here is the error: for(int j = 0; j < boardSize.width; ++i) you increment i not j
Oh, so it was a typo again! :X Well, however I still get 0 successes when the method finishes. :/
Are you sure that fileList[i] has the correct path? Did you check the image before you give it over to:
Yes I already checked that the List is correct (the method which generates list scans the files of a folder with
dirent.h
) Also thecv::Mat image
is not empty and has (As far as I can see it) good values.