Esempio n. 1
0
void
pcl::pcl_2d::edge::canny  (ImageType &output, ImageType &input)
{
  float tHigh = 50;
  float tLow = 20;
  const int height = input.size();
  const int width = input[0].size();
  /*noise reduction using gaussian blurring*/
  ImageType gaussian_kernel;
  conv_2d->gaussianKernel  (5, 1.4, gaussian_kernel);
  conv_2d->convolve  (output, gaussian_kernel, input);

  /*edge detection usign Sobel*/
  ImageType G;
  ImageType thet;
  sobelMagnitudeDirection  (G, thet, input);

  /*edge discretization*/
  float angle;
  for (int i = 0; i < height; i++)
  {
    for (int j = 0; j < width; j++)
    {
      angle = (thet[i][j] / 3.14f) * 180;
      if (((angle < 22.5) && (angle > -22.5)) || (angle > 157.5) || (angle < -157.5))
        thet[i][j] = 0;
      else
        if (((angle > 22.5) && (angle < 67.5)) || ((angle < -112.5) && (angle > -157.5)))
          thet[i][j] = 45;
        else
          if (((angle > 67.5) && (angle < 112.5)) || ((angle < -67.5) && (angle > -112.5)))
            thet[i][j] = 90;
          else
            if (((angle > 112.5) && (angle < 157.5)) || ((angle < -22.5) && (angle > -67.5)))
              thet[i][j] = 135;
    }
  }

  float max;
  /*tHigh and non-maximal supression*/
  for (int i = 1; i < height - 1; i++)
  {
    for (int j = 1; j < width - 1; j++)
    {
      if (G[i][j] < tHigh)
        continue;
      max = G[i][j];
      switch ((int)thet[i][j])
      {
        case 0:
          if(G[i][j] < G[i][j-1] || G[i][j] < G[i][j+1])
            G[i][j] = 0;
          break;
        case 45:
          if(G[i][j] < G[i-1][j+1] || G[i][j] < G[i+1][j-1])
            G[i][j] = 0;
          break;
        case 90:
          if(G[i][j] < G[i-1][j] || G[i][j] < G[i+1][j])
            G[i][j] = 0;
          break;
        case 135:
          if(G[i][j] < G[i-1][j-1] || G[i][j] < G[i+1][j+1])
            G[i][j] = 0;
          break;
      }
    }
  }

  /*edge tracing*/
  for (int i = 0; i < height; i++)
  {
    for (int j = 0; j < width; j++)
    {
      if (G[i][j] < tHigh)
        continue;
      switch ((int)thet[i][j])
      {
        case 0:
          cannyTraceEdge  (1, 0, i, j, 0, tLow, tHigh, G, thet);
          cannyTraceEdge  (-1, 0, i, j, 0, tLow, tHigh, G, thet);
          break;
        case 45:
          cannyTraceEdge  (1, 1, i, j, 45, tLow, tHigh, G, thet);
          cannyTraceEdge  (-1, -1, i, j, 45, tLow, tHigh, G, thet);
          break;
        case 90:
          cannyTraceEdge  (0, -1, i, j, 90, tLow, tHigh, G, thet);
          cannyTraceEdge  (0, 1, i, j, 90, tLow, tHigh, G, thet);
          break;
        case 135:
          cannyTraceEdge  (-1, 1, i, j, 135, tLow, tHigh, G, thet);
          cannyTraceEdge  (1, -1, i, j, 135, tLow, tHigh, G, thet);
          break;
      }
    }
  }

  /*final thresholding*/
  output.resize (height);
  for (int i = 0; i < height; i++)
  {
    output[i].resize (width);
    for (int j = 0; j < width; j++)
    {
      if (G[i][j] < tHigh)
        output[i][j] = 0;
      else
        output[i][j] = 255;
    }
  }
}
Esempio n. 2
0
template <typename PointInT, typename PointOutT> void
pcl_1_8::Edge<PointInT, PointOutT>::canny (
    const pcl::PointCloud<PointInT> &input_x, 
    const pcl::PointCloud<PointInT> &input_y,
    pcl::PointCloud<PointOutT> &output)
{
  float tHigh = hysteresis_threshold_high_;
  float tLow = hysteresis_threshold_low_;
  const int height = input_x.height;
  const int width = input_x.width;

  output.resize (height * width);
  output.height = height;
  output.width = width;

  // Noise reduction using gaussian blurring
  pcl::PointCloud<pcl::PointXYZI>::Ptr gaussian_kernel (new pcl::PointCloud<pcl::PointXYZI>);
  kernel_.setKernelSize (3);
  kernel_.setKernelSigma (1.0);
  kernel_.setKernelType (kernel<pcl::PointXYZI>::GAUSSIAN);
  kernel_.fetchKernel (*gaussian_kernel);
  convolution_.setKernel (*gaussian_kernel);

  PointCloudIn smoothed_cloud_x;
  convolution_.setInputCloud (input_x.makeShared());
  convolution_.filter (smoothed_cloud_x);

  PointCloudIn smoothed_cloud_y;
  convolution_.setInputCloud (input_y.makeShared());
  convolution_.filter (smoothed_cloud_y);


  // Edge detection usign Sobel
  pcl::PointCloud<PointXYZIEdge>::Ptr edges (new pcl::PointCloud<PointXYZIEdge>);
  sobelMagnitudeDirection (smoothed_cloud_x, smoothed_cloud_y, *edges.get ());

  // Edge discretization
  discretizeAngles (*edges);

  pcl::PointCloud<pcl::PointXYZI>::Ptr maxima (new pcl::PointCloud<pcl::PointXYZI>);
  suppressNonMaxima (*edges, *maxima, tLow);

  // Edge tracing
  for (int i = 0; i < height; i++)
  {
    for (int j = 0; j < width; j++)
    {
      if ((*maxima)(j, i).intensity < tHigh || (*maxima)(j, i).intensity == std::numeric_limits<float>::max ())
        continue;

      (*maxima)(j, i).intensity = std::numeric_limits<float>::max ();
      cannyTraceEdge ( 1, 0, i, j, *maxima);
      cannyTraceEdge (-1, 0, i, j, *maxima);
      cannyTraceEdge ( 1, 1, i, j, *maxima);
      cannyTraceEdge (-1, -1, i, j, *maxima);
      cannyTraceEdge ( 0, -1, i, j, *maxima);
      cannyTraceEdge ( 0, 1, i, j, *maxima);
      cannyTraceEdge (-1, 1, i, j, *maxima);
      cannyTraceEdge ( 1, -1, i, j, *maxima);
    }
  }

  // Final thresholding
  for (int i = 0; i < height; i++)
  {
    for (int j = 0; j < width; j++)
    {
      if ((*maxima)(j, i).intensity == std::numeric_limits<float>::max ())
        output (j, i).magnitude = 255;
      else
        output (j, i).magnitude = 0;
    }
  }
}