Visual Vibration Tracking 0.2
Загрузка...
Поиск...
Не найдено
camera_calibrator.cpp
1#include "CamCalib\camera_calibrator.h"
2
3CameraCalibrator::CameraCalibrator(std::string chessboards_path) :
4 chessboards_folder_path_{ chessboards_path },
5 winname_{ "Camera Calibrator" }
6{
7 // наших углов должен быть 10 и 7 по горизонтали и вертикали соответственно
8 pattern_size_ = Size(10, 7);
9
10 txt_file_name_ = "parameters.txt";
11 namedWindow(winname_, WINDOW_NORMAL);
12}
13
14CameraCalibrator::~CameraCalibrator()
15{
16 destroyWindow(winname_);
17}
18
19int CameraCalibrator::ExecuteCameraCalibration()
20{
21 std::cout << "Starting camera calibration..." << std::endl;
22
23 // Загружаем изображения в память
25
26 auto it = images_with_chessboard_.begin();
27 while (it != images_with_chessboard_.end())
28 {
29 Mat current_image = *it;
30 if (FindCorners(current_image, pattern_size_, corners_))
31 {
32 std::cout << "Pattern found" << std::endl;
33 drawChessboardCorners(current_image, pattern_size_, corners_, true);
34 vec_of_corners_.push_back(corners_);
35 }
36
37 it++;
38 AddTips(current_image, "Current frame: " + std::to_string(std::distance(images_with_chessboard_.begin(), it)) + "/" + std::to_string(images_with_chessboard_.size()));
39 imshow(winname_, current_image);
40
41 int code = waitKey(20);
42 switch (code)
43 {
44 // Пауза
45 // Клавиши - пробел (ASCII code)
46 case 32:
47 {
48 waitKey(0);
49 break;
50 }
51 case 'q':
52 {
53 it = images_with_chessboard_.end();
54 return 0;
55 break;
56 }
57 }
58 }
59
60 // Создаем координатную плоскость
61 std::vector<Point3f> object_points;
62 for (int i = 0; i < pattern_size_.height; i++)
63 {
64 for (int j = 0; j < pattern_size_.width; j++)
65 {
66 object_points.push_back(Point3f(i, j, 0));
67 }
68 }
69 std::vector<std::vector<Point3f>> vec_of_object_points(vec_of_corners_.size());
70 for (int i = 0; i < vec_of_corners_.size(); i++)
71 {
72 vec_of_object_points[i] = object_points;
73 }
75
76 std::cout << "Camera calibration..." << std::endl;
77 float error = calibrateCamera
78 (
79 vec_of_object_points,
84 rotation_vector_,
85 translation_vector_
86 );
87 std::cout << "Error is " << error << std::endl;
88 std::cout << "camera_matrix_ is " << camera_matrix_ << std::endl;
89 std::cout << "distortion_coefficients_ is " << distortion_coefficients_ << std::endl;
90
91 for (int i = 0; i < rotation_vector_.size(); i++)
92 {
93 std::cout << "rotation_vector_ is " << rotation_vector_[i] << std::endl;
94 }
95 for (int i = 0; i < translation_vector_.size(); i++)
96 {
97 std::cout << "translation_vector_ is " << translation_vector_[i] << std::endl;
98 }
99
100 // saving found parameters to a txt file
102 return 1;
103}
104
105int CameraCalibrator::LoadImages(std::string chessboards_path)
106{
107 Mat image_with_chessboard;
108 std::string image_name = chessboards_path;
110
111 image_with_chessboard = ReadNextImage(image_name);
112
113 // Инициализируем ширину и высоту кадра
114 frame_width_ = image_with_chessboard.size().width;
115 frame_height_ = image_with_chessboard.size().height;
116
117 while (!image_with_chessboard.empty())
118 {
119 images_with_chessboard_.push_back(image_with_chessboard);
120 imshow(winname_, image_with_chessboard);
121 image_with_chessboard = ReadNextImage(image_name);
122
123 int code = waitKey(20);
124 switch (code)
125 {
126 // Пауза
127 // Клавиши - пробел (ASCII code)
128 case 32:
129 {
130 waitKey(0);
131 break;
132 }
133 case 'q':
134 {
135 return 0;
136 break;
137 }
138 }
139 }
140 return 1;
141}
142
144{
145 Mat image;
146 path += std::to_string(chessboards_amount_++);
147 path += EXTENTION;
148 image = imread(path);
149 return image;
150}
151
152void CameraCalibrator::AddTips(Mat& frame, std::string tip)
153{
154 int font = FONT_HERSHEY_PLAIN;
155 double font_scale = 1.5;
156 int thickness = 2;
157
158 putText(
159 frame,
160 tip,
161 Point(frame.cols * 0.05, frame.rows * 0.05),
162 font,
163 font_scale,
164 Scalar(0, 255, 0),
165 thickness
166 );
167}
168
169bool CameraCalibrator::FindCorners(Mat input_frame, Size pattern_size, std::vector<Point2f>& corners)
170{
171 Mat gray_frame;
172 if (input_frame.channels() > 2)
173 cvtColor(input_frame, input_frame, COLOR_BGR2GRAY);
174
175 input_frame.copyTo(gray_frame);
176
177 bool pattern_found = findChessboardCorners
178 (
179 gray_frame,
180 pattern_size,
181 corners,
182 CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK
183 );
184
185 if (pattern_found)
186 cornerSubPix
187 (
188 gray_frame, corners,
189 Size(11, 11), // window size
190 Size(-1, -1), // zero zone
191 TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 40, 0.001)
192 );
193
194 return pattern_found;
195}
196
197void CameraCalibrator::SaveFoundParamsToFile(Mat camera_matrix, Mat dist_coeffs_2be_written)
198{
199 std::string filename = HelperFunctions::GenerateCsvFilename("parameters_");
200
201 fx_ = camera_matrix.at<double>(0, 0);
202 fy_ = camera_matrix.at<double>(1, 1);
203 px_ = camera_matrix.at<double>(0, 2);
204 py_ = camera_matrix.at<double>(1, 2);
205
206 std::vector<double> distortion_coefficients;
207 distortion_coefficients =
208 {
209 dist_coeffs_2be_written.at<double>(0,0),
210 dist_coeffs_2be_written.at<double>(0,1),
211 dist_coeffs_2be_written.at<double>(0,2),
212 dist_coeffs_2be_written.at<double>(0,3),
213 dist_coeffs_2be_written.at<double>(0,4)
214 };
215
216 std::ofstream file;
217 file.open(filename, std::ios::out | std::ios::trunc);
218
219 file << "fx;" + HelperFunctions::ToStringWithPrecision(fx_) << std::endl;
220 file << "fy;" + HelperFunctions::ToStringWithPrecision(fy_) << std::endl;
221 file << "px;" + HelperFunctions::ToStringWithPrecision(px_) << std::endl;
222 file << "py;" + HelperFunctions::ToStringWithPrecision(py_) << std::endl;
223 file << "dist;" + HelperFunctions::ToStringWithPrecision(distortion_coefficients[0]) + ";" + HelperFunctions::ToStringWithPrecision(distortion_coefficients[1])
224 + ";" + HelperFunctions::ToStringWithPrecision(distortion_coefficients[2]) + ";" + HelperFunctions::ToStringWithPrecision(distortion_coefficients[3]) + ";" + HelperFunctions::ToStringWithPrecision(distortion_coefficients[4]);
225
226 file.close();
227}
std::vector< Point2f > corners_
Найденные узлы шахматной доски, найденные на конкретном изображении
double frame_height_
Высота кадра
Mat camera_matrix_
Матрица, в которой находятся найденные коэффициенты px, py, cx, cy.
void AddTips(Mat &frame, std::string tip)
По аналогии с FrameHandler::AddTips добавляет подсказки пользователя. В данном случае это - номер тек...
std::vector< Mat > images_with_chessboard_
Вектор загруженных фотографий с шахматными досками
void SaveFoundParamsToFile(Mat camera_matrix, Mat dist_coeffs_2be_written)
Сохраняет найденные параметры (коэффициенты fx, fy, cx, cy), необходимые для удаления дисторсии
std::string winname_
Название окна
CameraCalibrator(std::string chessboards_path)
Конструктор этого класса
Mat distortion_coefficients_
Коэффициенты дисторсии
double py_
Коэффициент матрицы VideoUndistorter::camera_matrix_.
Mat ReadNextImage(std::string path)
Считывает новое изображение и увеличивает переменную chessboard_amount_ на один
double fy_
Коэффициент матрицы VideoUndistorter::camera_matrix_.
double px_
Коэффициент матрицы VideoUndistorter::camera_matrix_.
std::string txt_file_name_
Путь к текстовому файлу, в который будут сохранены найденные коэффициенты
int chessboards_amount_
Количество фотографий шахматных досок (находится в CameraCalibrator::LoadImages)
double fx_
Коэффициент матрицы VideoUndistorter::camera_matrix_.
double frame_width_
Ширина кадра
bool FindCorners(Mat input_frame, Size pattern_size, std::vector< Point2f > &corners)
Находит шахматный паттерн размером, заданным в конструкторе класса (CameraCalibrator::CameraCalibrato...
int LoadImages(std::string chessboards_path)
Загружает фотографии (изображения) шахматных досок в память из пути к папке.
Size pattern_size_
Размер паттерна, по которому будут искаться шахматные доски
std::vector< std::vector< Point2f > > vec_of_corners_
Контейнер для хранения найденных узлов шахматных досок
std::string chessboards_folder_path_
Путь к папке с фотографиями "шахматной доски".
std::string GenerateCsvFilename(std::string additional_text="")
Генерирует имя CSV файла для сохранения метаданных
Definition: helper.cpp:3
std::string ToStringWithPrecision(const T value, const int n=9)
Выполняет округление числа с определенной точностью
Definition: helper.h:49