Advertisement
Guest User

Untitled

a guest
Jan 21st, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.72 KB | None | 0 0
  1. #include "opencv2\core.hpp"
  2. #include "opencv2\imgcodecs.hpp"
  3. #include "opencv2\imgproc.hpp"
  4. #include "opencv2\highgui.hpp"
  5. #include "opencv2\aruco.hpp"
  6. #include "opencv2\calib3d.hpp"
  7. #include "opencv2\world.hpp"
  8.  
  9. #include <sstream>
  10. #include <iostream>
  11. #include <fstream>
  12.  
  13. using namespace std;
  14. using namespace cv;
  15.  
  16. const float calibrationSquareDimension = 0.027f; //meters
  17. const float arucoSquareDimension = 0.1016f; //meters
  18. const Size chessboardDimensions = Size(6, 9);
  19.  
  20. // Config Variables
  21. const String cameraCalName = "IloveCameraCalibration";
  22. const String windowNameCam = "WebCam";
  23. // Ab Part 15
  24.  
  25.  
  26. void createArucoMarkers() {
  27.  
  28. Mat outputMarker;
  29.  
  30. Ptr<aruco::Dictionary> markerDictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50); //Macht Probleme!
  31.  
  32. for (int i = 0; i < 50; i++)
  33. {
  34.  
  35. aruco::drawMarker(markerDictionary, i, 500, outputMarker, 1);
  36. ostringstream convert;
  37. convert << "4x4Marker_" << i << ".jpg";
  38. imwrite(convert.str(), outputMarker);
  39. }
  40.  
  41. }
  42.  
  43.  
  44. void createKnownBoardPosition(Size boardSize, float squareEdgeLength, vector<Point3f>& corners) {
  45.  
  46. for (int i = 0; i < boardSize.height; i++) {
  47. for (int j = 0; j < boardSize.width; j++) {
  48. corners.push_back(Point3f(j * squareEdgeLength, i * squareEdgeLength, 0.0f));
  49. }
  50. }
  51.  
  52. }
  53.  
  54. void getChessboardCorners(vector<Mat> images, vector<vector<Point2f>>& allFoundCorners, bool showResults = false) {
  55.  
  56. for (vector<Mat>::iterator iter = images.begin(); iter != images.end(); iter++)
  57. {
  58. vector<Point2f> pointBuf;
  59. bool found = findChessboardCorners(*iter, Size(9, 6), pointBuf, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE);
  60.  
  61. if (found) {
  62. allFoundCorners.push_back(pointBuf);
  63. }
  64.  
  65. if (showResults) {
  66. drawChessboardCorners(*iter, Size(9, 6), pointBuf, found);
  67. imshow("Looking for Corners", *iter);
  68. waitKey(0);
  69. }
  70.  
  71. }
  72.  
  73. }
  74.  
  75. void cameraCalibration(vector<Mat> calibrationImages, Size boardSize, float squareEdgeLength, Mat& cameraMatrix, Mat& distanceCoefficients) {
  76.  
  77. vector<vector<Point2f>> checkerBoardImageSpacePoints;
  78. getChessboardCorners(calibrationImages, checkerBoardImageSpacePoints, false);
  79.  
  80. vector<vector<Point3f>> worldSpaceCornerPoints(1);
  81.  
  82. createKnownBoardPosition(boardSize, squareEdgeLength, worldSpaceCornerPoints[0]);
  83. worldSpaceCornerPoints.resize(checkerBoardImageSpacePoints.size(), worldSpaceCornerPoints[0]);
  84.  
  85. vector<Mat> rVectors, tVectors;
  86. distanceCoefficients = Mat::zeros(8, 1, CV_64F);
  87.  
  88. calibrateCamera(worldSpaceCornerPoints, checkerBoardImageSpacePoints, boardSize, cameraMatrix, distanceCoefficients, rVectors, tVectors);
  89.  
  90. }
  91.  
  92. bool saveCameraCalibration(string name, Mat cameraMatrix, Mat distanceCoefficients) {
  93. ofstream outStream(name);
  94. if (outStream) {
  95. uint16_t rows = cameraMatrix.rows;
  96. uint16_t columns = cameraMatrix.cols;
  97.  
  98. outStream << rows << endl;
  99. outStream << columns << endl;
  100.  
  101. for (int r = 0; r < rows; r++)
  102. {
  103. for (int c = 0; c < columns; c++)
  104. {
  105. double value = cameraMatrix.at<double>(r, c);
  106. outStream << value << endl;
  107. }
  108. }
  109.  
  110. rows = distanceCoefficients.rows;
  111. columns = distanceCoefficients.cols;
  112.  
  113. outStream << rows << endl;
  114. outStream << columns << endl;
  115.  
  116. for (int r = 0; r < rows; r++)
  117. {
  118. for (int c = 0; c < columns; c++)
  119. {
  120. double value = distanceCoefficients.at<double>(r, c);
  121. outStream << value << endl;
  122. }
  123. }
  124.  
  125. outStream.close();
  126. return true;
  127.  
  128. }
  129.  
  130. return false;
  131. }
  132.  
  133. bool loadCameraCalibration(string name, Mat& cameraMatrix, Mat& distanceCoefficients) {
  134. ifstream inStream(name);
  135. if (inStream) {
  136. uint16_t rows;
  137. uint16_t columns;
  138.  
  139. inStream >> rows;
  140. inStream >> columns;
  141.  
  142. cameraMatrix = Mat(Size(columns, rows), CV_64F);
  143.  
  144. for (int r = 0; r < rows; r++) {
  145.  
  146. for (int c = 0; c < columns; c++) {
  147.  
  148. double read = 0.0f;
  149. inStream >> read;
  150. cameraMatrix.at<double>(r, c) = read;
  151. cout << cameraMatrix.at<double>(r, c) << "\n";
  152.  
  153. }
  154.  
  155. }
  156.  
  157. //Distance Coefficients
  158. inStream >> rows;
  159. inStream >> columns;
  160.  
  161. distanceCoefficients = Mat::zeros(rows, columns, CV_64F);
  162.  
  163. for (int r = 0; r < rows; r++) {
  164.  
  165. for (int c = 0; c < columns; c++) {
  166.  
  167. double read = 0.0f;
  168. inStream >> read;
  169. distanceCoefficients.at<double>(r, c) = read;
  170. cout << distanceCoefficients.at<double>(r, c) << "\n";
  171.  
  172. }
  173.  
  174. }
  175. inStream.close();
  176.  
  177. return true;
  178.  
  179. }
  180.  
  181. return false;
  182.  
  183. }
  184. /*
  185. int startWebcamMonitoring(const Mat& cameraMatrix, const Mat& distanceCoefficients, float squareDimensions) {
  186.  
  187. Mat frame;
  188.  
  189. vector<int> markerIds;
  190. vector<vector<Point2f>> markerCorners, rejectedCandidates;
  191. aruco::DetectorParameters parameters;
  192.  
  193. Ptr<aruco::Dictionary> markerDictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_4X4_50);
  194.  
  195. VideoCapture vid(0);
  196.  
  197. if (!vid.isOpened()) {
  198. return -1;
  199. }
  200.  
  201. namedWindow(windowNameCam, CV_WINDOW_AUTOSIZE);
  202.  
  203. //Ab hier werden die Figuren gerendert, hier nur Koordinatensystem
  204. vector<Vec3d> rotationVectors, translationVectors;
  205.  
  206. while (true) {
  207.  
  208. if (!vid.read(frame)) {
  209. break;
  210. }
  211.  
  212. aruco::detectMarkers(frame, markerDictionary, markerCorners, markerIds);
  213. aruco::estimatePoseSingleMarkers(markerCorners, arucoSquareDimension, cameraMatrix, distanceCoefficients, rotationVectors, translationVectors);
  214.  
  215. for (int i = 0; i < markerIds.size(); i++) {
  216. aruco::drawAxis(frame, cameraMatrix, distanceCoefficients, rotationVectors[i], translationVectors[i], 0.1f);
  217. }
  218.  
  219. imshow(windowNameCam, frame);
  220. if (waitKey(30) >= 0) break;
  221.  
  222. }
  223.  
  224. return 1;
  225.  
  226. }
  227. */
  228. void cameraCalibrationProcess(Mat& cameraMatrix, Mat& distanceCoefficients) {
  229.  
  230.  
  231. Mat frame;
  232. Mat drawToFrame;
  233.  
  234. vector<Mat> savedImages;
  235.  
  236. vector<vector<Point2f>> markerCorners, rejectedCandidates;
  237.  
  238. VideoCapture vid(0);
  239.  
  240. if (!vid.isOpened()) {
  241. return;
  242. }
  243.  
  244. int framePerSecond = 20;
  245.  
  246. namedWindow(windowNameCam, CV_WINDOW_AUTOSIZE);
  247.  
  248. while (true) {
  249. if (!vid.read(frame)) {
  250. break;
  251. }
  252.  
  253. vector<Vec2f> foundPoints;
  254. bool found = false;
  255.  
  256. found = findChessboardCorners(frame, chessboardDimensions, foundPoints, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE);
  257. frame.copyTo(drawToFrame);
  258. drawChessboardCorners(drawToFrame, chessboardDimensions, foundPoints, found);
  259.  
  260. if (found) {
  261. imshow(windowNameCam, drawToFrame);
  262. }
  263. else {
  264. imshow(windowNameCam, frame);
  265. }
  266.  
  267. char character = waitKey(1000 / framePerSecond);
  268.  
  269. switch (character) {
  270. case ' ':
  271. //saving image
  272. cout << "Attempting to save image.\n";
  273. if (found) {
  274. cout << "Image saved.\n";
  275. Mat temp;
  276. frame.copyTo(temp);
  277. savedImages.push_back(temp);
  278. }
  279. else {
  280. cout << "No image found.\n";
  281. }
  282. break;
  283. case 13:
  284. //start calibration
  285. cout << "Start calibration. \n";
  286. if (savedImages.size() > 25) {
  287. cout << "Starting calibration. \n";
  288. cameraCalibration(savedImages, chessboardDimensions, calibrationSquareDimension, cameraMatrix, distanceCoefficients);
  289. saveCameraCalibration(cameraCalName, cameraMatrix, distanceCoefficients);
  290. }
  291. else { cout << "Not enough Images. \n"; }
  292. break;
  293. case 27:
  294. cout << "Exiting calibration. \n";
  295. //exit
  296. return;
  297. break;
  298. }
  299. }
  300.  
  301. }
  302.  
  303. int main(int argv, char** argc) {
  304.  
  305. //createArucoMarkers();
  306.  
  307.  
  308. Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
  309.  
  310. Mat distanceCoefficients;
  311.  
  312. // Dieses hier zuerst ausführen um Kamerawerte zu erhalten:
  313. cameraCalibrationProcess(cameraMatrix, distanceCoefficients);
  314. //loadCameraCalibration(cameraCalName, cameraMatrix, distanceCoefficients);
  315. //startWebcamMonitoring(cameraMatrix, distanceCoefficients, 0.099f); /* 0.099 ist die Größe der Quadrate des Trackers in Metern */
  316.  
  317.  
  318.  
  319. return 0;
  320.  
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement