Advertisement
Guest User

Untitled

a guest
Oct 19th, 2017
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.73 KB | None | 0 0
  1. #include "opencv2/core/core.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include "opencv2/calib3d/calib3d.hpp"
  4. #include "opencv2/highgui/highgui.hpp"
  5. #include <iostream>
  6.  
  7. using namespace cv;
  8. using namespace std;
  9.  
  10. #define EPSILON 1E-5
  11.  
  12.  
  13. cv::Point2f center(0, 0);
  14.  
  15. cv::Point2f computeIntersect(cv::Vec4i a,
  16. cv::Vec4i b)
  17. {
  18. int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
  19. float denom;
  20.  
  21. if (float d = ((float)(x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)))
  22. {
  23. cv::Point2f pt;
  24. pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
  25. pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
  26. return pt;
  27. }
  28. else
  29. return cv::Point2f(-1, -1);
  30. }
  31.  
  32. void sortCorners(std::vector<cv::Point2f>& corners,
  33. cv::Point2f center)
  34. {
  35. std::vector<cv::Point2f> top, bot;
  36.  
  37. for (int i = 0; i < corners.size(); i++)
  38. {
  39. if (corners[i].y < center.y)
  40. top.push_back(corners[i]);
  41. else
  42. bot.push_back(corners[i]);
  43. }
  44. corners.clear();
  45.  
  46. if (top.size() == 2 && bot.size() == 2) {
  47. cv::Point2f tl = top[0].x > top[1].x ? top[1] : top[0];
  48. cv::Point2f tr = top[0].x > top[1].x ? top[0] : top[1];
  49. cv::Point2f bl = bot[0].x > bot[1].x ? bot[1] : bot[0];
  50. cv::Point2f br = bot[0].x > bot[1].x ? bot[0] : bot[1];
  51.  
  52.  
  53. corners.push_back(tl);
  54. corners.push_back(tr);
  55. corners.push_back(br);
  56. corners.push_back(bl);
  57. }
  58. }
  59.  
  60. struct Ray
  61. {
  62. cv::Vec3f origin;
  63. cv::Vec3f direction;
  64.  
  65. };
  66.  
  67.  
  68.  
  69. bool linePlaneIntersection(Vec3d* contact, Vec3d ray, Vec3d rayOrigin,
  70. Vec3d normal, Vec3d coord) {
  71. // get d value
  72. float d = normal.dot(coord);
  73.  
  74. if (normal.dot(ray) == 0) {
  75. return false; // No intersection, the line is parallel to the plane
  76. }
  77.  
  78. // Compute the X value for the directed line ray intersecting the plane
  79. float x = (d - normal.dot(rayOrigin)) / normal.dot(ray);
  80.  
  81. // output contact point
  82. *contact = rayOrigin + normalize(ray)*x; //Make sure your ray vector is normalized
  83. return true;
  84. }
  85.  
  86. cv::Point2f snapPoint;
  87. bool isClicked = false;
  88.  
  89. void onmouse(int event, int x, int y, int flags, void* param)
  90. {
  91. if (event == CV_EVENT_LBUTTONDOWN)
  92. {
  93. snapPoint.x = x;
  94. snapPoint.y = y;
  95.  
  96. //Mat &img = *((Mat*)(param)); // 1st cast it back, then deref
  97. //circle(img, Point(x, y), 50, Scalar(0, 255, 0), 1);
  98. isClicked = true;
  99. }
  100. }
  101. std::vector<cv::Point3d> Generate3DPoints()
  102. {
  103. std::vector<cv::Point3d> points;
  104.  
  105. double x, y, z;
  106.  
  107. x = .5; y = .5; z = -.5;
  108. points.push_back(cv::Point3d(x, y, z));
  109.  
  110. x = .5; y = .5; z = .5;
  111. points.push_back(cv::Point3d(x, y, z));
  112.  
  113. x = -.5; y = .5; z = .5;
  114. points.push_back(cv::Point3d(x, y, z));
  115.  
  116. x = -.5; y = .5; z = -.5;
  117. points.push_back(cv::Point3d(x, y, z));
  118.  
  119. x = .5; y = -.5; z = -.5;
  120. points.push_back(cv::Point3d(x, y, z));
  121.  
  122. x = -.5; y = -.5; z = -.5;
  123. points.push_back(cv::Point3d(x, y, z));
  124.  
  125. x = -.5; y = -.5; z = .5;
  126. points.push_back(cv::Point3d(x, y, z));
  127.  
  128. /*
  129. for(unsigned int i = 0; i < points.size(); ++i)
  130. {
  131. std::cout << points[i] << std::endl;
  132. }
  133. */
  134. return points;
  135. }
  136.  
  137. std::vector<cv::Point2d> Generate2DPoints()
  138. {
  139. std::vector<cv::Point2d> points;
  140.  
  141. float x, y;
  142.  
  143. x = 282; y = 274;
  144. points.push_back(cv::Point2d(x, y));
  145.  
  146. x = 397; y = 227;
  147. points.push_back(cv::Point2d(x, y));
  148.  
  149. x = 577; y = 271;
  150. points.push_back(cv::Point2d(x, y));
  151.  
  152. x = 462; y = 318;
  153. points.push_back(cv::Point2d(x, y));
  154.  
  155. x = 270; y = 479;
  156. points.push_back(cv::Point2d(x, y));
  157.  
  158. x = 450; y = 523;
  159. points.push_back(cv::Point2d(x, y));
  160.  
  161. x = 566; y = 475;
  162. points.push_back(cv::Point2d(x, y));
  163.  
  164. for (unsigned int i = 0; i < points.size(); ++i)
  165. {
  166. std::cout << points[i] << std::endl;
  167. }
  168.  
  169. return points;
  170. }
  171.  
  172. int main(int argc, char** argv)
  173. {
  174.  
  175.  
  176. Mat src, src_copy, edges, dst;
  177. src = imread("freezeFrame__1508152029892.png", 0);
  178.  
  179. namedWindow("My window", 1);
  180.  
  181. imshow("My window", src);
  182. while (1 && isClicked == false)
  183. {
  184. setMouseCallback("My window", onmouse, &src); // pass address of img here
  185. cv::waitKey(10);
  186. while (isClicked != false)
  187. {
  188. isClicked = false;
  189.  
  190. std::vector< cv::Point2f > corners;
  191.  
  192. // maxCorners – The maximum number of corners to return. If there are more corners
  193. // than that will be found, the strongest of them will be returned
  194. int maxCorners = 10;
  195.  
  196. // qualityLevel – Characterizes the minimal accepted quality of image corners;
  197. // the value of the parameter is multiplied by the by the best corner quality
  198. // measure (which is the min eigenvalue, see cornerMinEigenVal() ,
  199. // or the Harris function response, see cornerHarris() ).
  200. // The corners, which quality measure is less than the product, will be rejected.
  201. // For example, if the best corner has the quality measure = 1500,
  202. // and the qualityLevel=0.01 , then all the corners which quality measure is
  203. // less than 15 will be rejected.
  204. double qualityLevel = 0.01;
  205.  
  206. // minDistance – The minimum possible Euclidean distance between the returned corners
  207. double minDistance = 20.;
  208.  
  209. // mask – The optional region of interest. If the image is not empty (then it
  210. // needs to have the type CV_8UC1 and the same size as image ), it will specify
  211. // the region in which the corners are detected
  212. cv::Mat mask;
  213.  
  214. // blockSize – Size of the averaging block for computing derivative covariation
  215. // matrix over each pixel neighborhood, see cornerEigenValsAndVecs()
  216. int blockSize = 3;
  217.  
  218. // useHarrisDetector – Indicates, whether to use operator or cornerMinEigenVal()
  219. bool useHarrisDetector = false;
  220.  
  221. // k – Free parameter of Harris detector
  222. double k = 0.04;
  223.  
  224. cv::goodFeaturesToTrack(src, corners, maxCorners, qualityLevel, minDistance, mask, blockSize, useHarrisDetector, k);
  225.  
  226. for (size_t i = 0; i < corners.size(); i++)
  227. {
  228. cv::circle(src, corners[i], 10, cv::Scalar(0, 255, 255), -1);
  229. }
  230.  
  231. for (size_t i = 0; i < corners.size(); i++)
  232. {
  233. cv::Point2f pt1 = corners[i];
  234. for (int j = 0; j < corners.size(); j++)
  235. {
  236. cv::Point2f pt2 = corners[j];
  237. line(src, pt1, pt2, cv::Scalar(0, 255, 0));
  238. }
  239. }
  240.  
  241. corners.push_back(snapPoint);
  242.  
  243. Mat cameraIntrinsics(3, 3, CV_64FC1);
  244.  
  245. cameraIntrinsics.at<double>(0, 0) = 1.6003814935684204;
  246. cameraIntrinsics.at<double>(0, 1) = 0;
  247. cameraIntrinsics.at<double>(0, 2) = -0.0021958351135253906;
  248. cameraIntrinsics.at<double>(1, 0) = 0;
  249. cameraIntrinsics.at<double>(1, 1) = 1.6003814935684204;
  250. cameraIntrinsics.at<double>(1, 2) = -0.0044271680526435375;
  251. cameraIntrinsics.at<double>(2, 0) = 0;
  252. cameraIntrinsics.at<double>(2, 1) = 0;
  253. cameraIntrinsics.at<double>(2, 2) = 1;
  254.  
  255.  
  256.  
  257.  
  258. Mat invCameraIntrinsics = cameraIntrinsics.inv();
  259. cout << "inv" << invCameraIntrinsics;
  260. std::vector<cv::Vec3d> pointsTransformed3D;
  261.  
  262. std::vector<cv::Vec3d> points3D;
  263. for (int i = 0; i < corners.size(); i++)
  264. {
  265. cv::Vec3d pt;
  266.  
  267. pt[2] = 1.0f;
  268.  
  269. pt[0] = (corners[i].x / 1280) * 2 - 1;
  270. pt[1] = (corners[i].y / 720) * 2 - 1;
  271.  
  272. points3D.push_back(pt);
  273. }
  274. cv::transform(points3D, pointsTransformed3D, invCameraIntrinsics);
  275.  
  276. std::vector<Ray> rays;
  277. for (int i = 0; i < corners.size(); i++)
  278. {
  279.  
  280. Ray ray;
  281.  
  282. ray.origin = Vec3f(0, 0, 0);
  283. ray.direction = Vec3f(pointsTransformed3D[i][0], pointsTransformed3D[i][1], pointsTransformed3D[i][2]);
  284.  
  285. rays.push_back(ray);
  286. }
  287.  
  288.  
  289. std::vector<cv::Vec3d> contacts;
  290.  
  291. for (int i = 0; i < pointsTransformed3D.size(); i++)
  292. {
  293. Vec3d pt(pointsTransformed3D[i][0], pointsTransformed3D[i][1], pointsTransformed3D[i][2]);
  294.  
  295.  
  296. cv::Vec3d contact;
  297. if (linePlaneIntersection(&contact, rays[i].direction, rays[i].origin, normalize(Vec3f(0, 1, 0)), pt))
  298. {
  299.  
  300. contacts.push_back(contact);
  301. }
  302. }
  303.  
  304.  
  305. Mat rotationMatrix(3, 3, CV_64FC1);
  306.  
  307. rotationMatrix.at<double>(0, 0) = 0.9115078799790896;
  308. rotationMatrix.at<double>(0, 1) = -0.1883612409043686;
  309. rotationMatrix.at<double>(0, 2) = -0.3656137684237178;
  310. rotationMatrix.at<double>(1, 0) = -0.3046835686704949;
  311. rotationMatrix.at<double>(1, 1) = 0.2878667580409447;
  312. rotationMatrix.at<double>(1, 2) = -0.9079100465339108;
  313. rotationMatrix.at<double>(2, 0) = 0.2762631132059388;
  314. rotationMatrix.at<double>(2, 1) = 0.9389636694462479;
  315. rotationMatrix.at<double>(2, 2) = 0.2050022432604093;
  316.  
  317. cv::Mat rVec(3, 1, CV_64FC1); // Rotation vector
  318. Rodrigues(rotationMatrix, rVec);
  319. double norm = cv::norm(rVec);
  320.  
  321. double theta = (double)(sqrt(rVec.at<double>(0)*rVec.at<double>(0) + rVec.at<double>(1)*rVec.at<double>(1) + rVec.at<double>(2)*rVec.at<double>(2)) * 180 / 3.14567898726);
  322.  
  323. cv::Mat tVec(3, 1, CV_64FC1); // Translation vector
  324. tVec.at<double>(0) = 21.408294677734375;
  325. tVec.at<double>(1) = 531.1319580078125;
  326. tVec.at<double>(2) = 705.74224853515625;
  327.  
  328. cv::Mat distCoeffs(5, 1, CV_64FC1); // Distortion vector
  329. distCoeffs.at<double>(0) = 0;
  330. distCoeffs.at<double>(1) = 0;
  331. distCoeffs.at<double>(2) = 0;
  332. distCoeffs.at<double>(3) = 0;
  333. distCoeffs.at<double>(4) = 0;
  334.  
  335. std::vector<cv::Point2d> projectedPoints;
  336. std::vector < cv::Point3d> ContactPoints;
  337.  
  338. for (int i = 0; i < contacts.size(); i++)
  339. {
  340. cv::Point3d pt;
  341.  
  342. pt.x = contacts[i][0];
  343. pt.y = contacts[i][1];
  344. pt.z = contacts[i][2];
  345.  
  346. ContactPoints.push_back(pt);
  347. }
  348.  
  349.  
  350. cv::projectPoints(ContactPoints, rVec, tVec, cameraIntrinsics, distCoeffs, projectedPoints);
  351.  
  352.  
  353. for (size_t i = 0; i < projectedPoints.size(); i++)
  354. {
  355. cv::Point2d pt;
  356.  
  357. pt.x = projectedPoints[i].x* 1280;
  358. pt.y = projectedPoints[i].y* 720;
  359.  
  360. cv::circle(src, pt, 10, cv::Scalar(255, 0, 255), -1);
  361. }
  362.  
  363. imshow("My window", src);
  364. }
  365. }
  366.  
  367. cv:waitKey(0);
  368. return 0;
  369. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement