Exemplo n.º 1
0
template<typename PointInT, typename PointOutT> void
pcl_1_8::Edge<PointInT, PointOutT>::detectEdgeCanny (pcl::PointCloud<PointOutT> &output)
{
  float tHigh = hysteresis_threshold_high_;
  float tLow = hysteresis_threshold_low_;
  const int height = input_->height;
  const int width = input_->width;

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

  //pcl::console::TicToc tt;
  //tt.tic ();
  
  // Noise reduction using gaussian blurring
  pcl::PointCloud<pcl::PointXYZI>::Ptr gaussian_kernel (new pcl::PointCloud<pcl::PointXYZI>);
  PointCloudInPtr smoothed_cloud (new PointCloudIn);
  kernel_.setKernelSize (3);
  kernel_.setKernelSigma (1.0);
  kernel_.setKernelType (kernel<pcl::PointXYZI>::GAUSSIAN);
  kernel_.fetchKernel (*gaussian_kernel);
  convolution_.setKernel (*gaussian_kernel);
  convolution_.setInputCloud (input_);
  convolution_.filter (*smoothed_cloud);
  //PCL_ERROR ("Gaussian blur: %g\n", tt.toc ()); tt.tic ();
  
  // Edge detection usign Sobel
  pcl::PointCloud<PointXYZIEdge>::Ptr edges (new pcl::PointCloud<PointXYZIEdge>);
  setInputCloud (smoothed_cloud);
  detectEdgeSobel (*edges);
  //PCL_ERROR ("Sobel: %g\n", tt.toc ()); tt.tic ();
  
  // Edge discretization
  discretizeAngles (*edges);
  //PCL_ERROR ("Discretize: %g\n", tt.toc ()); tt.tic ();

  // tHigh and non-maximal supression
  pcl::PointCloud<pcl::PointXYZI>::Ptr maxima (new pcl::PointCloud<pcl::PointXYZI>);
  suppressNonMaxima (*edges, *maxima, tLow);
  //PCL_ERROR ("NM suppress: %g\n", tt.toc ()); tt.tic ();

  // 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);
    }
  }
  //PCL_ERROR ("Edge tracing: %g\n", tt.toc ());

  // Final thresholding
  for (size_t i = 0; i < input_->size (); ++i)
  {
    if ((*maxima)[i].intensity == std::numeric_limits<float>::max ())
      output[i].magnitude = 255;
    else
      output[i].magnitude = 0;
  }
}
Exemplo 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;
    }
  }
}
Exemplo n.º 3
0
int main(int argc, char **argv)
{
	// Process command line
	if (argc < 3)
		Usage(argc, argv);

	std::string inputFilename = argv[1];
	std::string outputFilename = argv[2];

	for (int i = 3; i < argc - 1; i += 2)
	{
		if (std::string(argv[i]) == std::string("-q"))
			QLim = atof(argv[i+1]);
		else if (std::string(argv[i]) == std::string("-w"))
			WLimF = atof(argv[i+1]);
		else if (std::string(argv[i]) == std::string("-f"))
			FilterSize = atoi(argv[i+1]);
		else if (std::string(argv[i]) == std::string("-m"))
			NonMaximaBoxSize = atoi(argv[i+1]);
	}

	// Load image
	image = new Ga::Image(inputFilename);

	// Calculate tensor
	Gu = new float[image->sizeX() * image->sizeY()];
	Gv = new float[image->sizeX() * image->sizeY()];
	Guv = new float[image->sizeX() * image->sizeY()];

	computeStructureTensor(Gu, Gv, Guv);

	// Apply boxfilter
	computeBoxFilter(Gu, FilterSize);
	computeBoxFilter(Gv, FilterSize);
	computeBoxFilter(Guv, FilterSize);

	// Calculate interest values
	result = new Ga::Image(typeid(float), image->sizeX(), image->sizeY());

	double wmean = 0;
	double normalization = 0;

	for (int y = 0; y < result->sizeY(); y++)
	{
		for (int x = 0; x < result->sizeX(); x++)
		{
			int index = y * image->sizeX() + x;

			float trace = Gu[index] + Gv[index];
			float determinant = (Gu[index] * Gv[index]) - (Guv[index] * Guv[index]);

			float w = determinant / trace;
			float q = (4 * determinant) / (trace * trace);

			// Test for qlim and calculate wlim
			if (q > QLim)
			{
				result->setPixel(x, y, w);
				wmean += w;
				normalization++;
			}
			else
				result->setPixel(x, y, 0);
		}
	}

	WLim = (wmean / normalization) * WLimF;

	for (int y = 0; y < result->sizeY(); y++)
	{
		for (int x = 0; x < result->sizeX(); x++)
		{
			int index = y * image->sizeX() + x;

			float trace = Gu[index] + Gv[index];
			float determinant = (Gu[index] * Gv[index]) - (Guv[index] * Guv[index]);

			float w = determinant / trace;

			// Test for wlim
			if (w <= WLim)
				result->setPixel(x, y, 0);
		}
	}

	// Suppress local non-maxima
	suppressNonMaxima(NonMaximaBoxSize);

	// Write result image
	result->write(outputFilename.c_str());

	// Release memory
	delete image;
	delete result;
	delete[] Gu;
	delete[] Gv;
	delete[] Guv;

	// Return
	return 0;
}