Advertisement
lamiastella

Object3D.cpp (joe)

Jun 23rd, 2017
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.48 KB | None | 0 0
  1. #include "Object3D.h"
  2. #include "Visualizer.h"
  3. #include "Util.h"
  4.  
  5.  
  6. Object3D::Object3D()
  7. {
  8.  
  9. }
  10.  
  11. Object3D::Object3D(cv::Mat cluster)
  12. {
  13.     // Step 1: Initialize variables
  14.     rightEdgeConnected = false;
  15.     leftEdgeConnected = false;
  16.     hasHand = false;
  17.     hasPlane = false;
  18.     hasShape = false;
  19.  
  20.     // Step 1: determine whether cluster is hand
  21.     printf("checking for hand!\n");
  22.     //if (checkForHand(cluster, 0.005, 0.25)) //original value
  23.     if (checkForHand(cluster, 0.005, 0.3))
  24.     {
  25.         hand = Hand(cluster, 50);
  26.         hasHand = true;
  27.         printf("has hand!\n");
  28.         return;
  29.     }
  30.    
  31.    
  32.     // Step 2: determine whether there is a plane
  33.    
  34.     plane = new Plane(cluster);
  35.     // Step 2.1 If there is plane, remove plane and look for hand
  36.     auto points = plane->getPlaneIndicies();
  37.  
  38.     if (points.size() != 0)
  39.     {
  40.         hasPlane = true;
  41.  
  42.         for (auto i = 0; i < points.size();i++)
  43.         {
  44.             auto x = points[i].x;
  45.             auto y = points[i].y;
  46.             cluster.at<cv::Vec3f>(y, x)[0] = 0;
  47.             cluster.at<cv::Vec3f>(y, x)[1] = 0;
  48.             cluster.at<cv::Vec3f>(y, x)[2] = 0;
  49.         }
  50.  
  51.         auto center = Util::findCentroid(cluster);
  52.         cv::Mat hand_cluster = cv::Mat::zeros(cluster.rows, cluster.cols, cluster.type());
  53.         Util::floodFill(center.x, center.y, cluster, hand_cluster, 0.02);
  54.  
  55.         if (checkForHand(hand_cluster, -0.99, 0.2))
  56.         {
  57.             hand = Hand(hand_cluster, 30);
  58.             auto finger_length = Util::euclidianDistance3D(hand.fingers_xyz[0], hand.centroid_xyz);
  59.  
  60.             if (finger_length > 0.03 && finger_length < 0.2)
  61.             {
  62.                 hasHand = true;
  63.                 return;
  64.             }
  65.         }
  66.     }
  67.    
  68.    
  69.     // Step 2.1.1 If there is plane, no hand, then the rest of points are shape
  70.     shape = cluster;
  71.     hasShape = true;
  72. }
  73.  
  74. Hand Object3D::getHand() const
  75. {
  76.     return hand;
  77. }
  78.  
  79. Plane Object3D::getPlane() const
  80. {
  81.     return *plane;
  82. }
  83.  
  84. cv::Mat Object3D::getShape() const
  85. {
  86.     return shape;
  87. }
  88.  
  89. double Object3D::centroidCircleSweep(cv::Mat cluster, double distance) const
  90. {
  91.     cv::Mat channels[3];
  92.     cv::split(cluster, channels);
  93.     auto show_img = Visualizer::visualizeXYZMap(cluster);
  94.     // Step 1: Find the center
  95.     auto m = cv::moments(channels[2], false);
  96.     cv::Point center(m.m10 / m.m00, m.m01 / m.m00);
  97.     cv::circle(show_img, center, 2, cv::Scalar(255, 0, 0),2);
  98.     // Step 2: Find the radius (pixels) that correspond to distance (meters)
  99.     auto distancePerPixel = Util::euclideanDistancePerPixel(cluster, center, 5);
  100.     int radius = distance / distancePerPixel;
  101.     if (radius <= 0 || radius > cluster.cols / 4)
  102.     {
  103.         return -1;
  104.     }  
  105.  
  106.     // Step 3: Extract all pixels within distance
  107.     cv::Mat binary_img;
  108.     cv::normalize(channels[2], binary_img, 0, 255, cv::NORM_MINMAX, CV_8UC1);
  109.     cv::Mat mask = cv::Mat::zeros(binary_img.size(), binary_img.type());
  110.     cv::Mat dstImg = cv::Mat::zeros(binary_img.size(), binary_img.type());
  111.     cv::circle(mask, center, radius, cv::Scalar(255, 255, 255));
  112.     binary_img.copyTo(dstImg, mask);
  113.  
  114.     auto covered = 0;
  115.  
  116.     for (auto r = center.y; r > 0; r--)
  117.     {
  118.         for (auto c = 0; c < dstImg.cols; c++)
  119.         {
  120.             if (dstImg.at<uchar>(r, c) != 0)
  121.             {
  122.                 covered++;
  123.             }
  124.         }
  125.     }
  126.  
  127.     auto coverage = static_cast<double>(covered) / cv::countNonZero(mask);
  128.     return coverage;
  129. }
  130.  
  131. bool Object3D::checkForHand(cv::Mat cluster, double min_coverage, double max_coverage, double pointer_finger_distance)
  132. {
  133.     checkEdgeConnected(cluster);
  134.     if ((rightEdgeConnected && !leftEdgeConnected) || (leftEdgeConnected && rightEdgeConnected))
  135.     {
  136.         auto coverage = centroidCircleSweep(cluster, pointer_finger_distance*2);
  137.         if (coverage < max_coverage && coverage > min_coverage)
  138.         {
  139.             return true;
  140.         }
  141.     }
  142.  
  143.     return false;
  144. }
  145.  
  146. void Object3D::checkEdgeConnected(cv::Mat cluster)
  147. {
  148.     auto cols = cluster.cols;
  149.     auto rows = cluster.rows;
  150.  
  151.     // Bottom Sweep
  152.     auto r = static_cast<int>(rows * 0.9);
  153.     for (auto c = 0; c < cols / 4 ; c++)
  154.     {
  155.         if (cluster.at<cv::Vec3f>(r, c)[2] != 0)
  156.         {
  157.             leftEdgeConnected = true;
  158.             break;
  159.         }
  160.     }
  161.  
  162.     // Left Side Sweep
  163.     auto c = static_cast<int>(cols * 0.2);
  164.     for (auto r2 = 0; r2 < rows; r2++)
  165.     {
  166.         if (cluster.at<cv::Vec3f>(r2, c)[2] != 0)
  167.         {
  168.             leftEdgeConnected = true;
  169.             break;
  170.         }
  171.     }
  172.  
  173.     // Bottom Sweep
  174.     r = static_cast<int>(rows * 0.9);
  175.     for (auto c2 = cols / 4; c2 < cols; c2++)
  176.     {
  177.         if (cluster.at<cv::Vec3f>(r, c2)[2] != 0)
  178.         {
  179.             rightEdgeConnected = true;
  180.             break;
  181.         }
  182.     }
  183.  
  184.     // Right Side Sweep
  185.     c = static_cast<int>(cols * 0.8);
  186.     for (auto r2 = rows / 2; r2 < rows; r2++)
  187.     {
  188.         if (cluster.at<cv::Vec3f>(r2, c)[2] != 0)
  189.         {
  190.             rightEdgeConnected = true;
  191.             break;
  192.         }
  193.     }
  194.  
  195. }
  196.  
  197.  
  198. Object3D::~Object3D()
  199. {
  200.  
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement