Guest User

Untitled

a guest
Dec 24th, 2017
448
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.62 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 "opencv2/world.hpp"
  6.  
  7.  
  8. #include <iostream>
  9.  
  10. using namespace cv;
  11. using namespace std;
  12.  
  13. #define EPSILON 1E-5
  14.  
  15.  
  16. cv::Point2f center(0, 0);
  17.  
  18. cv::Point2f computeIntersect(cv::Vec4i a,
  19. cv::Vec4i b)
  20. {
  21. 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];
  22. float denom;
  23.  
  24. if (float d = ((float)(x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)))
  25. {
  26. cv::Point2f pt;
  27. pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
  28. pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
  29. return pt;
  30. }
  31. else
  32. return cv::Point2f(-1, -1);
  33. }
  34.  
  35. void sortCorners(std::vector<cv::Point2f>& corners,
  36. cv::Point2f center)
  37. {
  38. std::vector<cv::Point2f> top, bot;
  39.  
  40. for (int i = 0; i < corners.size(); i++)
  41. {
  42. if (corners[i].y < center.y)
  43. top.push_back(corners[i]);
  44. else
  45. bot.push_back(corners[i]);
  46. }
  47. corners.clear();
  48.  
  49. if (top.size() == 2 && bot.size() == 2) {
  50. cv::Point2f tl = top[0].x > top[1].x ? top[1] : top[0];
  51. cv::Point2f tr = top[0].x > top[1].x ? top[0] : top[1];
  52. cv::Point2f bl = bot[0].x > bot[1].x ? bot[1] : bot[0];
  53. cv::Point2f br = bot[0].x > bot[1].x ? bot[0] : bot[1];
  54.  
  55.  
  56. corners.push_back(tl);
  57. corners.push_back(tr);
  58. corners.push_back(br);
  59. corners.push_back(bl);
  60. }
  61. }
  62.  
  63. struct Ray
  64. {
  65. cv::Vec3f origin;
  66. cv::Vec3f direction;
  67.  
  68. };
  69.  
  70.  
  71.  
  72. std::pair<bool, double> linePlaneIntersection( Vec3f direction, Vec3f rayOrigin,
  73. Vec3f normal, Vec3f coord) {
  74. double denom = normalize(normal).dot(direction);
  75. double d = -(normalize(normal).dot(coord));
  76.  
  77. if (std::abs(denom) < std::numeric_limits<double>::epsilon())
  78. {
  79. // Parallel
  80. return std::pair<bool, double>(false, (double)0);
  81. }
  82. else
  83. {
  84. double nom = normalize(normal).dot(normalize(rayOrigin)) + d;
  85. double t = -(nom / denom);
  86. return std::pair<bool, double>(t >= 0, (double)t);
  87. }
  88.  
  89. }
  90.  
  91. cv::Point2f snapPoint;
  92. bool isClicked = false;
  93.  
  94. void onmouse(int event, int x, int y, int flags, void* param)
  95. {
  96. if (event == CV_EVENT_LBUTTONDOWN)
  97. {
  98. snapPoint.x = x;
  99. snapPoint.y = y;
  100.  
  101. //Mat &img = *((Mat*)(param)); // 1st cast it back, then deref
  102. //circle(img, Point(x, y), 50, Scalar(0, 255, 0), 1);
  103. isClicked = true;
  104. }
  105. }
  106. std::vector<cv::Point3d> Generate3DPoints()
  107. {
  108. std::vector<cv::Point3d> points;
  109.  
  110. double x, y, z;
  111.  
  112. x = .5; y = .5; z = -.5;
  113. points.push_back(cv::Point3d(x, y, z));
  114.  
  115. x = .5; y = .5; z = .5;
  116. points.push_back(cv::Point3d(x, y, z));
  117.  
  118. x = -.5; y = .5; z = .5;
  119. points.push_back(cv::Point3d(x, y, z));
  120.  
  121. x = -.5; y = .5; z = -.5;
  122. points.push_back(cv::Point3d(x, y, z));
  123.  
  124. x = .5; y = -.5; z = -.5;
  125. points.push_back(cv::Point3d(x, y, z));
  126.  
  127. x = -.5; y = -.5; z = -.5;
  128. points.push_back(cv::Point3d(x, y, z));
  129.  
  130. x = -.5; y = -.5; z = .5;
  131. points.push_back(cv::Point3d(x, y, z));
  132.  
  133. /*
  134. for(unsigned int i = 0; i < points.size(); ++i)
  135. {
  136. std::cout << points[i] << std::endl;
  137. }
  138. */
  139. return points;
  140. }
  141.  
  142. std::vector<cv::Point2d> Generate2DPoints()
  143. {
  144. std::vector<cv::Point2d> points;
  145.  
  146. float x, y;
  147.  
  148. x = 282; y = 274;
  149. points.push_back(cv::Point2d(x, y));
  150.  
  151. x = 397; y = 227;
  152. points.push_back(cv::Point2d(x, y));
  153.  
  154. x = 577; y = 271;
  155. points.push_back(cv::Point2d(x, y));
  156.  
  157. x = 462; y = 318;
  158. points.push_back(cv::Point2d(x, y));
  159.  
  160. x = 270; y = 479;
  161. points.push_back(cv::Point2d(x, y));
  162.  
  163. x = 450; y = 523;
  164. points.push_back(cv::Point2d(x, y));
  165.  
  166. x = 566; y = 475;
  167. points.push_back(cv::Point2d(x, y));
  168.  
  169. for (unsigned int i = 0; i < points.size(); ++i)
  170. {
  171. std::cout << points[i] << std::endl;
  172. }
  173.  
  174. return points;
  175. }
  176.  
  177. int main(int argc, char** argv)
  178. {
  179.  
  180.  
  181. Mat src, src_copy, edges, dst;
  182. src = imread("freezeFrame__1508152029892.png", 0);
  183.  
  184. namedWindow("My window", 1);
  185.  
  186. imshow("My window", src);
  187. while (1 && isClicked == false)
  188. {
  189. setMouseCallback("My window", onmouse, &src); // pass address of img here
  190. cv::waitKey(10);
  191. while (isClicked != false)
  192. {
  193. isClicked = false;
  194.  
  195. std::vector< cv::Point2f > corners;
  196.  
  197. // maxCorners – The maximum number of corners to return. If there are more corners
  198. // than that will be found, the strongest of them will be returned
  199. int maxCorners = 10;
  200.  
  201. // qualityLevel – Characterizes the minimal accepted quality of image corners;
  202. // the value of the parameter is multiplied by the by the best corner quality
  203. // measure (which is the min eigenvalue, see cornerMinEigenVal() ,
  204. // or the Harris function response, see cornerHarris() ).
  205. // The corners, which quality measure is less than the product, will be rejected.
  206. // For example, if the best corner has the quality measure = 1500,
  207. // and the qualityLevel=0.01 , then all the corners which quality measure is
  208. // less than 15 will be rejected.
  209. double qualityLevel = 0.01;
  210.  
  211. // minDistance – The minimum possible Euclidean distance between the returned corners
  212. double minDistance = 20;
  213.  
  214. // mask – The optional region of interest. If the image is not empty (then it
  215. // needs to have the type CV_8UC1 and the same size as image ), it will specify
  216. // the region in which the corners are detected
  217. cv::Mat mask;
  218.  
  219. // blockSize – Size of the averaging block for computing derivative covariation
  220. // matrix over each pixel neighborhood, see cornerEigenValsAndVecs()
  221. int blockSize = 3;
  222.  
  223. // useHarrisDetector – Indicates, whether to use operator or cornerMinEigenVal()
  224. bool useHarrisDetector = false;
  225.  
  226. // k – Free parameter of Harris detector
  227. double k = 0.04;
  228.  
  229. cv::goodFeaturesToTrack(src, corners, maxCorners, qualityLevel, minDistance, mask, blockSize, useHarrisDetector, k);
  230.  
  231. for (size_t i = 0; i < corners.size(); i++)
  232. {
  233. cv::circle(src, corners[i], 10, cv::Scalar(0, 255, 255), -1);
  234. }
  235.  
  236.  
  237.  
  238. corners.push_back(snapPoint);
  239.  
  240. //Generate a camera intrinsic matrix
  241. Mat K = (Mat_<double>(3, 3)
  242. << 1600, 0,src.cols/2,
  243. 0, 1600,src.rows/2,
  244. 0, 0, 1);
  245.  
  246.  
  247.  
  248. Mat invCameraIntrinsics = K.inv();
  249. cout << "inv" << invCameraIntrinsics;
  250. std::vector<cv::Vec3d> pointsTransformed3D;
  251.  
  252. std::vector<cv::Vec3d> points3D;
  253. for (int i = 0; i < corners.size(); i++)
  254. {
  255. cv::Vec3d pt;
  256.  
  257. pt[2] = 1.0f;
  258.  
  259. pt[0] = (corners[i].x );
  260. pt[1] = (corners[i].y );
  261.  
  262. points3D.push_back(pt);
  263. }
  264.  
  265. cv::transform(points3D, pointsTransformed3D, invCameraIntrinsics);
  266.  
  267.  
  268. Mat rot = (Mat_<double>(3, 3)
  269. << 0.8744617, 0.2258282, -0.4293233,
  270. 0.0608088, 0.8270180, 0.5588771,
  271. 0.4812683, -0.5148232, 0.7094631);
  272.  
  273. std::vector<cv::Point3d> pointsRotated;
  274. Mat translVec(3, 1, CV_64F);
  275. translVec.at<double>(0, 0) = 21.408294677734375;
  276. translVec.at<double>(1, 0) = 531.1319580078125;
  277. translVec.at<double>(2, 0) = 705.74224853515625;
  278.  
  279. const Mat camera_translation = (-rot * translVec);
  280. cv::transform(pointsTransformed3D, pointsRotated, rot);
  281.  
  282. std::vector<Ray> rays;
  283. for (int i = 0; i < pointsTransformed3D.size(); i++)
  284. {
  285.  
  286. Ray ray;
  287.  
  288. ray.origin = Vec3f(camera_translation.at<double>(0,0), camera_translation.at<double>(1,0),
  289. camera_translation.at<double>(2,0));
  290. ray.direction = Vec3f(pointsRotated[i].x, pointsRotated[i].y, pointsRotated[i].z);
  291.  
  292. rays.push_back(ray);
  293. }
  294. std::vector<cv::Vec3f> contacts;
  295.  
  296. for (int i = 0; i < pointsRotated.size(); i++)
  297. {
  298. Vec3f pt(0, 0,0);
  299.  
  300. cv::Vec3f contact;
  301. std::pair<bool, double> test = linePlaneIntersection(rays[i].direction, rays[i].origin, Vec3f(0, 1, 0), pt);
  302. if (test.first == true)
  303. {
  304. cv::Vec3f contact(rays[i].origin + (rays[i].direction) * test.second);
  305. contacts.push_back(contact);
  306. }
  307. }
  308.  
  309.  
  310.  
  311. std::vector<Vec6f> outputlines;
  312. for (int i = 0; i < contacts.size(); i++)
  313. {
  314. cv::Vec3f p1;
  315. p1[0] = contacts[i][0];
  316. p1[1] = contacts[i][1];
  317. p1[2] = contacts[i][2];
  318. for (int j = i + 1; j < contacts.size(); j++)
  319. {
  320.  
  321. cv::Vec3f p2;
  322. p2[0] = contacts[j][0];
  323. p2[1] = contacts[j][1];
  324. p2[2] = contacts[j][2];
  325.  
  326. for (int b = j + 1; b < contacts.size(); b++)
  327. {
  328. cv::Vec3f p3;
  329. p3[0] = contacts[b][0];
  330. p3[1] = contacts[b][1];
  331. p3[2] = contacts[b][2];
  332.  
  333. std::vector<cv::Vec3f> lines;
  334.  
  335. lines.push_back(p1);
  336. lines.push_back(p2);
  337. lines.push_back(p3);
  338.  
  339. Vec6f lineOutput;
  340. cv::fitLine(lines, lineOutput, CV_DIST_L2, 0, 0.01, 0.01);
  341.  
  342. outputlines.push_back(lineOutput);
  343.  
  344. }
  345. }
  346. }
  347.  
  348. /*
  349. std::vector<Ray> rays;
  350. for (int i = 0; i < pointsTransformed3D.size(); i++)
  351. {
  352.  
  353. Ray ray;
  354.  
  355. ray.origin = Vec3f(0, 0, 0);
  356. ray.direction = Vec3f(pointsTransformed3D[i][0], pointsTransformed3D[i][1], pointsTransformed3D[i][2]);
  357.  
  358. rays.push_back(ray);
  359. }
  360.  
  361.  
  362. ViewSpacePoint.x = (2 * screenX) / screenWidth;
  363. ViewSpacePoint.y = (2 * screenY) / screenHeight;
  364. ViewSpacePoint.z = 1 / tan(cameraFieldOfViewInRadians / 2);
  365.  
  366. WorldPoint = ViewSpacePoint * inverseOfViewMatrix;
  367.  
  368.  
  369. std::vector<cv::Vec3f> contacts;
  370.  
  371. for (int i = 0; i < pointsTransformed3D.size(); i++)
  372. {
  373. Vec3f pt(pointsTransformed3D[pointsTransformed3D.size()-1][0], pointsTransformed3D[pointsTransformed3D.size() - 1][1],
  374. pointsTransformed3D[pointsTransformed3D.size() - 1][2]);
  375.  
  376. cv::Vec3f contact;
  377. std::pair<bool, double> test = linePlaneIntersection(rays[i].direction, rays[i].origin, Vec3f(0, 1, 0), pt);
  378. if (test.first == true)
  379. {
  380. cv::Vec3f contact(rays[i].origin + (rays[i].direction) * test.second);
  381. contacts.push_back(contact);
  382. }
  383. }
  384.  
  385. std::vector<cv::Vec3d> pointsOnPlane;
  386. std::vector<cv::Vec3d> pointsAbovePlane;
  387. for (int i = 0; i < contacts.size(); i++)
  388. {
  389. Vec3d sub = contacts[i];
  390. Vec3d normal = Vec3d(0, 1, 0);
  391. float d = -normal.dot(sub);
  392. pointsOnPlane.push_back(sub);
  393. if (-sub[1] < std::numeric_limits<double>::epsilon())
  394. {
  395.  
  396. }
  397. else
  398. {
  399. pointsAbovePlane.push_back(sub);
  400. }
  401. }
  402.  
  403. std::vector<cv::Vec3d> pointsAbove;
  404.  
  405. for (int i = 0; i < pointsOnPlane.size(); i++)
  406. {
  407. Vec3d pt = pointsOnPlane[i];
  408. for (int j = 0; j < pointsAbovePlane.size(); j++ )
  409. {
  410. Vec3f direction = pointsAbovePlane[j] - pointsOnPlane[i] ;
  411.  
  412. }
  413. }
  414. */
  415. cv::Mat rvec, rMat = (cv::Mat_<double>(3, 3) << /* ( */1, 0, 0, 0, 1, 0, 0, 0, 1); //you had error here
  416. cv::Rodrigues(rMat, rvec);
  417. cv::Mat tvec = (cv::Mat_<double>(3, 1) <</* ( */ 0, 0, 0); //and here
  418.  
  419.  
  420. //Project the 3D Point onto 2D plane
  421. std::vector<cv::Point2d> points_2d;
  422. std::vector<cv::Point3d> points_3d;
  423.  
  424. for (int i = 0; i < outputlines.size(); i++)
  425. {
  426. cv::Point3d pt;
  427. pt.x = (outputlines[i][0]);
  428. pt.y = (outputlines[i][1]);
  429. pt.z = (outputlines[i][2]);
  430. points_3d.push_back(pt);
  431. }
  432.  
  433. projectPoints(points_3d, rvec, tvec, K, Mat(), points_2d);
  434.  
  435. for (size_t i = 0; i < points_2d.size(); i++)
  436. {
  437. cv::Point2d pt;
  438.  
  439. pt.x = points_2d[i].x;
  440. pt.y = points_2d[i].y;
  441.  
  442. cv::circle(src, pt, 10, cv::Scalar(255, 0, 255), -1);
  443. }
  444.  
  445.  
  446. for (size_t i = 0; i < points_2d.size(); i++)
  447. {
  448. cv::Point2f pt1 = points_2d[i];
  449. for (int j = i + 1; j < points_2d.size(); j++)
  450. {
  451. cv::Point2f pt2 = points_2d[j];
  452. int length = 10;
  453. line(src, Point(pt2.x, pt2.y), Point(pt2.x + pt1.x * length, pt2.y + pt1.y * length), cv::Scalar(255, 0, 255), 3, 4);
  454.  
  455. }
  456. }
  457. imshow("My window", src);
  458. }
  459. }
  460.  
  461. cv:waitKey(0);
  462. return 0;
  463. }
Advertisement
Add Comment
Please, Sign In to add comment