Я пытался откалибровать камеру Iphone 11 Pro, и функция openCV calibrateCamera () возвращает ошибку более 1,2+ (то же самое для computeReprojectionErrors () ниже). Я хочу, чтобы они были ниже 0,5, потому что после этого я делаю карту несоответствия, и мне нужно, чтобы она была плавной. Как его минимизировать? Вот мой код, и я сделал 90 изображений платы под разными углами, которые хранятся в ../chess_image. Вот код: github.com/markilebyak/opencv.git
Также здесь: 4shared.com/folder/PSDaeTcI/opencv.html это 36 изображений из тех 90, которые я использовал, и 34 в оттенках серого с обнаружил строки из тех 36.
void createKnownBoardPosition(Size &boardSize, float squareEdgeLength, vector<Point3f>& corners) {
for (int i = 0; i < boardSize.height; i++) {
for (int j = 0; j < boardSize.width; j++) {
corners.emplace_back((float)j * squareEdgeLength, (float)i * squareEdgeLength, 0.0f);
}
}
}
void process_images(std::string &path_to_directory, Size &chessboard_size, vector<vector<Point2f>>& allFoundCorners) {
// Function to iterate through images
// taken for camera calibration
vector<String> filenames;
cv::glob(path_to_directory, filenames);
vector<Point2f> pointBuffer;
int counter = 0;
for (const auto & filename : filenames) {
if (filename != "../chess_images/.DS_Store"){
Mat im = imread(filename);
std::cout << filename << std::endl;
Mat gray_im;
cvtColor(im, gray_im, COLOR_BGR2GRAY);
bool found = findChessboardCorners(gray_im, chessboard_size, pointBuffer,
CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);
if (found) {
counter++;
TermCriteria criteria = TermCriteria( TermCriteria::EPS + TermCriteria::MAX_ITER,
30,0.0001 );
Size winSize = Size( 11, 11);
Size zeroZone = Size( -1, -1 );
//cornerSubPix is the algorithm focused on relocating the points. it receives the image, the corners
// a window size, zeroZone and the actual criteria. The window size is the search area.
cornerSubPix(gray_im, pointBuffer, winSize, zeroZone, criteria );
drawChessboardCorners( gray_im, chessboard_size, Mat(pointBuffer), found );
string nametext = "../drawn_chessboard/" + to_string(counter) + ".jpg";
imwrite(nametext, gray_im);
allFoundCorners.push_back(pointBuffer);
}
}
}
std::cout << "Images used: " << counter << std::endl;
}
double computeReprojectionErrors( const vector<vector<Point3f> >& objectPoints,
const vector<vector<Point2f> >& imagePoints,
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
const Mat& cameraMatrix , const Mat& distCoeffs,
vector<float>& perViewErrors, bool fisheye) {
vector<Point2f> imagePoints2;
size_t totalPoints = 0;
double totalErr = 0, err;
perViewErrors.resize(objectPoints.size());
for(size_t i = 0; i < objectPoints.size(); ++i )
{
if (fisheye)
{
fisheye::projectPoints(objectPoints[i], imagePoints2, rvecs[i], tvecs[i], cameraMatrix,
distCoeffs);
}
else
{
projectPoints(objectPoints[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2);
}
err = norm(imagePoints[i], imagePoints2, NORM_L2);
size_t n = objectPoints[i].size();
perViewErrors[i] = (float) std::sqrt(err*err/n);
totalErr += err*err;
totalPoints += n;
}
return std::sqrt(totalErr/totalPoints);
}
void calibration_process(Size &boardSize, float &squareEdgeLength, Mat& cameraMatrix, Mat& distortionCoefficients,
std::string &path_to_directory) {
vector<vector<Point2f>> checkerboardImageSpacePoints;
process_images(path_to_directory, boardSize, checkerboardImageSpacePoints);
vector<vector<Point3f>> worldSpaceCornerPoints(1);
createKnownBoardPosition(boardSize, squareEdgeLength, worldSpaceCornerPoints[0]);
worldSpaceCornerPoints.resize(checkerboardImageSpacePoints.size(), worldSpaceCornerPoints[0]);
//rotation and translation vectors (rVectors, tVectors)
vector<Mat> rVectors, tVectors;
distortionCoefficients = Mat::zeros(8, 1, CV_64F);
calibrateCamera(worldSpaceCornerPoints, checkerboardImageSpacePoints, boardSize, cameraMatrix,
distortionCoefficients, rVectors, tVectors, CALIB_FIX_K5 + CALIB_FIX_INTRINSIC);
vector<float> perViewErrors;
double rep_error = computeReprojectionErrors(worldSpaceCornerPoints, checkerboardImageSpacePoints, rVectors, tVectors, cameraMatrix,
distortionCoefficients, perViewErrors, false);
std::cout << "Reprojection Error: " << rep_error << std::endl;
}
int main() {
Mat cameraMatrix, distortionCoefficient;
Size chessboardDimensions = Size(6, 9);
float calibrationSquareDimension = 0.03f;
std::string path = "../chess_images";
calibration_process(chessboardDimensions, calibrationSquareDimension, cameraMatrix,
distortionCoefficient, path);
return 0;
}