Exemple #1
0
int main(int argc, char* argv[]) {
  gl::image img;
  img.from_pgm("data\\3.pgm");

  gl::image bw_img(img.size_x, img.size_y);
  threshold_filter(img, bw_img, 10);

  gl::recursive_contour center_circle;
  center_circle.search(gl::point(img.size_x / 2, img.size_y / 2), &bw_img);

  gl::point center = center_circle.mass_center();

  gl::point start = center;
  while (img.at(start) < 100) start.x += 1;

  for (int y = 0; y < img.size_y; ++y)
    for (int x = 0; x < img.size_x; ++x) {
      int c = img.at(x, y);
      assert(c >= 0);
      if (c < 60)
        img.at(x, y) = 0;
    }
      
  img.to_pgm("out.pgm");

  return 0;

  const double pi = 22.0 / 7.0;

  double rad_1 = 2 * pi / 360;  // ~0.017

  double angle = 0;
  double angle_delta = rad_1;
  
  double r = start.x - center.x;
  double r_delta = 0.032;

  int x = start.x, y = start.y;
  int last_x = x, last_y = y;
  while (x >= 0 && x < img.size_x && y >= 0 && y < img.size_y) {
    x = center.x + r * std::cos(angle);
    y = center.y + r * std::sin(angle);
    img.draw_line(gl::point(x, y), gl::point(last_x, last_y), 0);
    angle += angle_delta;
    r += r_delta;
    // angle_delta -= 0.005;
    // r_delta /= 1.05;
    last_x = x;
    last_y = y;
  }

  img.to_pgm("3-1.pgm");
  return 0;
}
cv::Mat ArmObjSegmentation::segment(cv::Mat& color_img, cv::Mat& depth_img, cv::Mat& self_mask,
                                    cv::Mat& table_mask, bool init_color_models)
{

  cv::Mat color_img_lab_uchar(color_img.size(), color_img.type());
  cv::Mat color_img_lab(color_img.size(), CV_32FC3);
  cv::cvtColor(color_img, color_img_lab_uchar, CV_BGR2HSV);
  // cv::cvtColor(color_img, color_img_lab_uchar, CV_BGR2Lab);
  color_img_lab_uchar.convertTo(color_img_lab, CV_32FC3, 1.0/255);
  cv::Mat tmp_bw(color_img.size(), CV_8UC1);
  cv::Mat bw_img(color_img.size(), CV_32FC1);
  // Convert to grayscale
  cv::cvtColor(color_img, tmp_bw, CV_BGR2GRAY);
  tmp_bw.convertTo(bw_img, CV_32FC1, 1.0/255);


#ifdef VISUALIZE_GRAPH_WEIGHTS
  cv::Mat fg_weights(color_img.size(), CV_32FC1, cv::Scalar(0.0));
  cv::Mat fg_tied_weights(color_img.size(), CV_32FC1, cv::Scalar(0.0));
  cv::Mat bg_tied_weights(color_img.size(), CV_32FC1, cv::Scalar(0.0));
  cv::Mat bg_weights(color_img.size(), CV_32FC1, cv::Scalar(0.0));
  cv::Mat wu_weights(color_img.size(), CV_32FC1, cv::Scalar(0.0));
  cv::Mat wl_weights(color_img.size(), CV_32FC1, cv::Scalar(0.0));
#endif // VISUALIZE_GRAPH_WEIGHTS

  // TODO: Clean this up once we have stuff working well
  cv::Mat inv_self_mask;
  cv::bitwise_not(self_mask, inv_self_mask);
  cv::Mat much_larger_mask(self_mask.size(), CV_8UC1, cv::Scalar(255));
  cv::Mat enlarge_element(bg_enlarge_size_, bg_enlarge_size_, CV_8UC1, cv::Scalar(255));
  cv::dilate(inv_self_mask, much_larger_mask, enlarge_element);
  cv::Mat larger_mask, known_arm_mask;
  cv::Mat arm_band = getArmBand(inv_self_mask, arm_enlarge_width_, arm_shrink_width_, false,
                                larger_mask, known_arm_mask);

  // Get known arm pixels
  cv::Mat known_arm_pixels;
  color_img_lab.copyTo(known_arm_pixels, known_arm_mask);
  cv::Mat known_bg_mask = much_larger_mask - larger_mask;

  // Get known object pixels
  cv::Mat known_bg_pixels;
  color_img_lab.copyTo(known_bg_pixels, known_bg_mask);

  // Get stats for building graph
  int num_nodes = 0;
  int num_edges = 0;

  tabletop_pushing::NodeTable nt;
  for (int r = 0; r < much_larger_mask.rows; ++r)
  {
    for (int c = 0; c < much_larger_mask.cols; ++c)
    {
      if (much_larger_mask.at<uchar>(r,c) > 0)
      {
        // Add this as another node
        int cur_idx = num_nodes++;
        nt.addNode(r, c, cur_idx);
        int test_idx = nt.getIdx(r,c);
        // Check for edges to add
        // left edge
        if (c > 0 && much_larger_mask.at<uchar>(r, c-1) > 0)
        {
          num_edges++;
        }
        if (r > 0)
        {
          // Up edge
          if(much_larger_mask.at<uchar>(r-1,c) > 0)
          {
            num_edges++;
          }
        }
      }
    }
  }
  if (num_nodes < 1)
  {
    cv::Mat empty(color_img.size(), CV_8UC1, cv::Scalar(0));
    return empty;
  }

  if (!have_arm_color_model_)
  {
    std::cout << "[arm_obj_segmentation]: Building arm color model." << std::endl;
    arm_color_model_ = getGMMColorModel(known_arm_pixels, known_arm_mask, 3);
    have_arm_color_model_ = true;
  }
  if(!have_bg_color_model_)
  {
    std::cout << "[arm_obj_segmentation]: Building bg color model." << std::endl;
    bg_color_model_ = getGMMColorModel(known_bg_pixels, known_bg_mask, 5);
    have_bg_color_model_ = true;
  }

#ifdef USE_CANNY_EDGES
  cv::Mat canny_edges_8bit;
  cv::Mat canny_edges;
  cv::Canny(tmp_bw, canny_edges_8bit, 120, 250);
  canny_edges_8bit.convertTo(canny_edges, CV_32FC1, 1.0/255);
#else
  cv::Mat Ix = getXImageDeriv(bw_img);
  cv::Mat Iy = getYImageDeriv(bw_img);
#endif
  cv::Mat Dx = getXImageDeriv(depth_img);
  cv::Mat Dy = getYImageDeriv(depth_img);
  tabletop_pushing::GraphType *g;
  g = new GraphType(num_nodes, num_edges);
  // Populate unary and binary edge weights
  for (int r = 0; r < much_larger_mask.rows; ++r)
  {
    for (int c = 0; c < much_larger_mask.cols; ++c)
    {
      if (much_larger_mask.at<uchar>(r,c) > 0)
      {
        int cur_idx = nt.getIdx(r,c);
        float fg_weight = 0.0;
        float bg_weight = 0.0;
        if (known_arm_mask.at<uchar>(r,c) > 0)
        {
          fg_weight = fg_tied_weight_;
          bg_weight = 0.0;
        }
        else if (known_bg_mask.at<uchar>(r,c) > 0 || table_mask.at<uchar>(r,c) > 0)
        {
          fg_weight = 0.0;
          bg_weight = bg_tied_weight_;
        }
        else
        {
          fg_weight = getUnaryWeight(color_img_lab.at<cv::Vec3f>(r,c), arm_color_model_);
          bg_weight = getUnaryWeight(color_img_lab.at<cv::Vec3f>(r,c), bg_color_model_)*0.5;
        }
        g->add_node();
        g->add_tweights(cur_idx, fg_weight, bg_weight);

#ifdef VISUALIZE_GRAPH_WEIGHTS
        fg_weights.at<float>(r,c) = fg_weight;
        bg_weights.at<float>(r,c) = bg_weight;
#endif // VISUALIZE_GRAPH_WEIGHTS

        // Add left link
        if (c > 0 && much_larger_mask.at<uchar>(r, c-1) > 0)
        {
          int other_idx = nt.getIdx(r, c-1);
#ifdef USE_CANNY_EDGES
          float w_l = getEdgeWeightBoundary(canny_edges.at<float>(r,c), Dx.at<float>(r,c),
                                            canny_edges.at<float>(r, c-1), Dx.at<float>(r, c-1));
#else // USE_CANNY_EDGES
          float w_l = getEdgeWeightBoundary(Ix.at<float>(r,c), Dx.at<float>(r,c),
                                            Ix.at<float>(r, c-1), Dx.at<float>(r, c-1));
#endif // USE_CANNY_EDGES
          g->add_edge(cur_idx, other_idx, /*capacities*/ w_l, w_l);

#ifdef VISUALIZE_GRAPH_WEIGHTS
          wl_weights.at<float>(r,c) = w_l;
#endif // VISUALIZE_GRAPH_WEIGHTS
        }
        if (r > 0)
        {
          // Add up link
          if(much_larger_mask.at<uchar>(r-1,c) > 0)
          {
            int other_idx = nt.getIdx(r-1, c);
#ifdef USE_CANNY_EDGES
            float w_u = getEdgeWeightBoundary(canny_edges.at<float>(r, c),   Dy.at<float>(r, c),
                                              canny_edges.at<float>(r-1, c), Dy.at<float>(r-1, c));
#else // USE_CANNY_EDGES
            float w_u = getEdgeWeightBoundary(Iy.at<float>(r,c), Dx.at<float>(r,c),
                                              Iy.at<float>(r, c-1), Dx.at<float>(r, c-1));
#endif // USE_CANNY_EDGES
            g->add_edge(cur_idx, other_idx, /*capacities*/ w_u, w_u);

#ifdef VISUALIZE_GRAPH_WEIGHTS
            wu_weights.at<float>(r,c) = w_u;
#endif // VISUALIZE_GRAPH_WEIGHTS
          }
        }
      }
    }
  }

  // Perform cut
  g->maxflow(false);
  // Convert output into image
  cv::Mat segs = convertFlowToMat(g, nt, color_img.rows, color_img.cols);
  // Cleanup
  delete g;

  cv::Mat graph_input;
  cv::Mat segment_arm;
  cv::Mat segment_bg;
  color_img.copyTo(graph_input, much_larger_mask);
  color_img.copyTo(segment_arm, segs);
  color_img.copyTo(segment_bg, (segs == 0));
  //cv::imshow("segments", segs);
  // cv::imshow("Graph input", graph_input);
  cv::imshow("Arm segment", segment_arm);
  cv::imshow("Background segment", segment_bg);
  cv::imshow("Table mask", table_mask);
  // cv::imshow("Known bg mask", known_bg_mask);

#ifdef VISUALIZE_GRAPH_WEIGHTS
  double min_val, max_val;
  cv::minMaxLoc(fg_weights, &min_val, &max_val);
  cv::imshow("fg weights", (fg_weights-min_val)/(max_val-min_val));
  // std::cout << "Max fg weight: " << max_val << std::endl;
  // std::cout << "Min fg weight: " << min_val << std::endl;

  cv::minMaxLoc(bg_weights, &min_val, &max_val);
  cv::imshow("bg weights", (bg_weights-min_val)/(max_val-min_val));
  // std::cout << "Max bg weight: " << max_val << std::endl;
  // std::cout << "Min bg weight: " << min_val << std::endl;

  // cv::minMaxLoc(wu_weights, &min_val, &max_val);
  // cv::imshow("up weights", wu_weights/max_val);
  // std::cout << "Max up weight: " << max_val << std::endl;
  // std::cout << "Min up weight: " << min_val << std::endl;

  // cv::minMaxLoc(wl_weights, &min_val, &max_val);
  // cv::imshow("left weights", wl_weights/max_val);
  // std::cout << "Max left weight: " << max_val << std::endl;
  // std::cout << "Min left weight: " << min_val << std::endl;
#endif // VISUALIZE_GRAPH_WEIGHTS
#ifdef USE_CANNY_EDGES
  cv::imshow("Canny", canny_edges);
#endif
  return segs;
}