fork(1) download
  1. #include "tracker.h"
  2.  
  3. #ifndef _WIN64
  4. #error "Project is not configured for x86 platform! If you have x86 version of OpenCV, link it to the project and remove this line."
  5. #endif
  6.  
  7. #pragma message(": warning PC001: Replace include and library path in project configuration to point to your installation of OpenCV. Also make sure the executable can locate the appropriate .dll file.")
  8.  
  9. using namespace mini;
  10. using namespace in;
  11. using namespace cv;
  12. using namespace std;
  13. using namespace DirectX;
  14.  
  15. const int Tracker::MIN_TRACKED_POINTS = 10;
  16. Mat src1;
  17. Mat src_gray1;
  18. double tw;
  19. double th;
  20. double cw;
  21. double ch;
  22. double f;
  23. double center_mm_y; // w milimetrach środek kartki papieru współrzędna y
  24. double center_mm_x; // w milimetrach środek kartki papieru współrzedna x
  25. double center_x; // w pixelach środek kartki papieru współrzędna x
  26. double center_y; // w pixelach środek kartki papieru współrzędna y
  27. Mat C;
  28.  
  29. Mat prev_pyramid;
  30. vector<Point2f> prev_pfp;
  31. vector<Point3f> prev_pto;
  32. bool isTracked;
  33.  
  34. Tracker::Tracker(const std::string& templateImage, cv::Size2f templateSize, cv::Size2f frameSize, double focalLength)
  35. {
  36. //TODO: Load image, find camera matrix, etc.
  37. src1 = imread(templateImage, IMREAD_COLOR);
  38. if (src1.empty()) {
  39. cout << "Could not open or find comic book image" << endl;
  40. return;
  41. }
  42. //imshow("source", src1);
  43. cvtColor(src1, src_gray1, CV_BGR2GRAY);
  44. //imshow("source gray", src_gray1);
  45. C = Mat(3, 3, CV_64FC1);
  46. tw = templateSize.width;
  47. th = templateSize.height;
  48. cw = frameSize.width;
  49. ch = frameSize.height;
  50. f = focalLength;
  51. C.at<double>(0, 0) = f;
  52. C.at<double>(0, 1) = 0.0f;
  53. C.at<double>(0, 2) = cw / 2.0f;
  54. C.at<double>(1, 0) = 0.0f;
  55. C.at<double>(1, 1) = f;
  56. C.at<double>(1, 2) = ch / 2.0f;
  57. C.at<double>(2, 0) = 0.0f;
  58. C.at<double>(2, 1) = 0.0f;
  59. C.at<double>(2, 2) = 1.0f;
  60. center_mm_y = th / 2.0f;
  61. center_mm_x = tw / 2.0f;
  62. center_x = src1.cols / 2.0f;
  63. center_y = src1.rows / 2.0f;
  64. }
  65. bool Tracker::Update(Mat currentFrame)
  66. {
  67. vector<Point2f> new_pfp; // punkty charakterystyczne na klatce video
  68. vector<Point3f> new_pto; // odległości względne od środka obrazka w milimetrach
  69.  
  70. //imshow("currentFrame", currentFrame);
  71. Mat src_gray2;
  72. cvtColor(currentFrame, src_gray2, CV_BGR2GRAY);
  73. //imshow("currentFrame grey", src_gray2);
  74. if (!isTracked) {
  75. // 7.2.1 Wyszukiwanie
  76. Mat descriptors1, descriptors2;
  77. vector<KeyPoint> keypoints1, keypoints2;
  78. Ptr<KAZE> detector = cv::KAZE::create();
  79. detector->detectAndCompute(src_gray1, noArray(), keypoints1, descriptors1);
  80. detector->detectAndCompute(src_gray2, noArray(), keypoints2, descriptors2);
  81. vector<DMatch> matches;
  82. Ptr<BFMatcher> matcher = cv::BFMatcher::create();
  83. if (keypoints2.size() == 0) {
  84. isTracked = false;
  85. return false;
  86. }
  87. matcher->match(descriptors1, descriptors2, matches);
  88.  
  89. double max_dist = 0; double min_dist = 100;
  90.  
  91. //-- Quick calculation of max and min distances between keypoints
  92. for (int i = 0; i < descriptors1.rows; i++)
  93. {
  94. double dist = matches[i].distance;
  95. if (dist < min_dist) min_dist = dist;
  96. if (dist > max_dist) max_dist = dist;
  97. }
  98.  
  99. vector< DMatch > good_matches;
  100.  
  101. for (int i = 0; i < descriptors1.rows; i++)
  102. {
  103. if (matches[i].distance < 3 * min_dist)
  104. {
  105. good_matches.push_back(matches[i]);
  106. }
  107. }
  108.  
  109. if (good_matches.size() == 0) {
  110. isTracked = false;
  111. return false;
  112. }
  113.  
  114. Mat result;
  115. drawMatches(src1, keypoints1, currentFrame, keypoints2,
  116. good_matches, result, Scalar::all(-1), Scalar::all(-1),
  117. vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
  118. //imshow("Video", result);
  119.  
  120. vector<Point2f> ptp; // punkty charakterystyczne na obiekcie
  121.  
  122. for (int i = 0; i < good_matches.size(); i++)
  123. {
  124. //-- Get the keypoints from the good matches
  125. Point2f objPoint = keypoints1[good_matches[i].queryIdx].pt;
  126. double p_x = objPoint.x; // kolumna
  127. double p_y = objPoint.y; // wiersz
  128. ptp.push_back(objPoint);
  129. double distx = (p_x * center_mm_x) / center_x - center_mm_x;
  130. double disty = (p_y * center_mm_y) / center_y - center_mm_y;
  131. new_pto.push_back(Point3f(distx, disty, 0));
  132. new_pfp.push_back(keypoints2[good_matches[i].trainIdx].pt);
  133. }
  134. }
  135. else {
  136. //7.2.2 Śledzenie
  137. vector<Point2f> pfp;
  138. vector<uchar> isFound;
  139. vector<float> errors;
  140. Mat pyramid;
  141. buildOpticalFlowPyramid(src_gray2, pyramid, Size(31, 31), 3);
  142. calcOpticalFlowPyrLK(prev_pyramid, pyramid, prev_pfp, pfp, isFound, errors);
  143. for (int i = 0; i < isFound.size(); i++) {
  144. uchar found = isFound[i];
  145. if (found == 1) {
  146. /*
  147. Po wywołaniu należy odrzucić pary punktów (pito, pifp), dla których nie
  148. udało się znaleźć nowego położenia punktu pifp.
  149. */
  150. new_pfp.push_back(pfp[i]);
  151. new_pto.push_back(prev_pto[i]);
  152. }
  153. }
  154. }
  155. //7.2.1.1 Estymacja położenia
  156. solvePnPRansac(new_pto, new_pfp, C, noArray(), rotationVector, translationVector);
  157.  
  158. //7.2.1.2 Ocena jakości estymacji
  159. vector<Point3f> objCorners; // w milimetrach
  160. vector<Point2f> objOnCameraCorners; // w pixelach
  161. objCorners.push_back(Point3f(-center_mm_x, -center_mm_y, 0));
  162. objCorners.push_back(Point3f(center_mm_x, -center_mm_y, 0));
  163. objCorners.push_back(Point3f(center_mm_x, center_mm_y, 0));
  164. objCorners.push_back(Point3f(-center_mm_x, center_mm_y, 0));
  165. projectPoints(objCorners, rotationVector, translationVector, C, noArray(), objOnCameraCorners);
  166.  
  167. for (int i = 0; i < objOnCameraCorners.size(); i++) {
  168. Point2f point = objOnCameraCorners[i];
  169. if (!(point.x <= src_gray2.cols && point.x >= 0 && point.y >= 0 && point.y <= src_gray2.rows)) {
  170. isTracked = false;
  171. return false;
  172. }
  173. }
  174. if (!isContourConvex(objOnCameraCorners)) {
  175. isTracked = false;
  176. return false;
  177. }
  178. double area = contourArea(objOnCameraCorners);
  179. double areaObj = contourArea(objCorners);
  180. if (area < 10) { //todo
  181. isTracked = false;
  182. return false;
  183. }
  184.  
  185. cout << "JUPII" << endl;
  186.  
  187. //7.2.1.3 Przygotowanie do śledzenia
  188. vector<Point2f> tracking;
  189. for (int i = 0; i < new_pfp.size(); i++) {
  190. if (pointPolygonTest(objOnCameraCorners, new_pfp[i], false) >= 0) {
  191. tracking.push_back(new_pfp[i]);
  192. }
  193. }
  194. if (tracking.size() < 5) {
  195. isTracked = false;
  196. return false;
  197. }
  198.  
  199. Mat pyramid;
  200. buildOpticalFlowPyramid(src_gray2, pyramid, Size(31, 31), 3);
  201.  
  202. //7.2.1.4 Macierz transformacji
  203. Mat R;
  204. Rodrigues(rotationVector, R);
  205. // R t
  206. // 0 1
  207. transformation = XMFLOAT4X4(R.at<float>(0, 1), R.at<float>(0, 2), R.at<float>(0, 3), translationVector.at<float>(0, 0),
  208. R.at<float>(1, 1), R.at<float>(1, 2), R.at<float>(1, 3), translationVector.at<float>(1, 0),
  209. R.at<float>(2, 1), R.at<float>(2, 2), R.at<float>(2, 3), translationVector.at<float>(2, 0),
  210. 1, 1, 1, 0);
  211.  
  212. prev_pyramid = pyramid;
  213. prev_pfp = tracking;
  214. prev_pto = new_pto;
  215. isTracked = true;
  216. return true;
  217. }
  218.  
  219. void Tracker::Reset()
  220. {
  221. //TODO: Clear object tracking data stored from previous frames
  222. isTracked = false;
  223. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:1:21: fatal error: tracker.h: No such file or directory
 #include "tracker.h"
                     ^
compilation terminated.
stdout
Standard output is empty