Beispiel #1
0
template <typename PointInT, typename PointOutT> void
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypointsForOctave (
  const PointCloudIn &input,
  KdTree &tree,
  float base_scale, int nr_scales_per_octave, PointCloudOut &output)
{
  // Compute the difference of Gaussians (DoG) scale space
  std::vector<float> scales (nr_scales_per_octave + 3);
  for (int i_scale = 0; i_scale <= nr_scales_per_octave + 2; ++i_scale)
  {
    scales[i_scale] = base_scale * pow (2.0, (1.0 * i_scale - 1) / nr_scales_per_octave);
  }
  Eigen::MatrixXf diff_of_gauss;
  computeScaleSpace (input, tree, scales, diff_of_gauss);

  // Find extrema in the DoG scale space
  std::vector<int> extrema_indices, extrema_scales;
  findScaleSpaceExtrema (input, tree, diff_of_gauss, extrema_indices, extrema_scales);

  // Add keypoints to output
  for (size_t i_keypoint = 0; i_keypoint < extrema_indices.size (); ++i_keypoint)
  {
    PointOutT keypoint;
    const int &keypoint_index = extrema_indices[i_keypoint];

    keypoint.x = input.points[keypoint_index].x;
    keypoint.y = input.points[keypoint_index].y;
    keypoint.z = input.points[keypoint_index].z;
    keypoint.scale = scales[extrema_scales[i_keypoint]];

    output.points.push_back (keypoint); 
  }
}
Beispiel #2
0
template <typename PointInT, typename PointOutT> void 
pcl::SIFTKeypoint<PointInT, PointOutT>::detectKeypointsForOctave (
    const PointCloudIn &input, KdTree &tree, float base_scale, int nr_scales_per_octave, 
    PointCloudOut &output, pcl::PointIndices &indices)
{
  // Compute the difference of Gaussians (DoG) scale space
  std::vector<float> scales (nr_scales_per_octave + 3);
  for (int i_scale = 0; i_scale <= nr_scales_per_octave + 2; ++i_scale)
  {
    scales[i_scale] = base_scale * powf (2.0f, (1.0f * static_cast<float> (i_scale) - 1.0f) / static_cast<float> (nr_scales_per_octave));
  }
  Eigen::MatrixXf diff_of_gauss;
  computeScaleSpace (input, tree, scales, diff_of_gauss);

  // Find extrema in the DoG scale space
  std::vector<int> extrema_indices, extrema_scales;
  findScaleSpaceExtrema (input, tree, diff_of_gauss, extrema_indices, extrema_scales);

  output.points.reserve (output.points.size () + extrema_indices.size ());
  indices.indices.reserve (indices.indices.size () + extrema_indices.size ());
  // Save scale?
  if (scale_idx_ != -1)
  {
    // Add keypoints to output
    for (size_t i_keypoint = 0; i_keypoint < extrema_indices.size (); ++i_keypoint)
    {
      PointOutT keypoint;
      const int &keypoint_index = extrema_indices[i_keypoint];
   
      keypoint.x = input.points[keypoint_index].x;
      keypoint.y = input.points[keypoint_index].y;
      keypoint.z = input.points[keypoint_index].z;
      memcpy (reinterpret_cast<char*> (&keypoint) + out_fields_[scale_idx_].offset,
              &scales[extrema_scales[i_keypoint]], sizeof (float));
      output.points.push_back (keypoint); 
      indices.indices.push_back (keypoint_index);
    }
  }
  else
  {
    // Add keypoints to output
    for (size_t i_keypoint = 0; i_keypoint < extrema_indices.size (); ++i_keypoint)
    {
      PointOutT keypoint;
      const int &keypoint_index = extrema_indices[i_keypoint];
   
      keypoint.x = input.points[keypoint_index].x;
      keypoint.y = input.points[keypoint_index].y;
      keypoint.z = input.points[keypoint_index].z;

      output.points.push_back (keypoint); 
      indices.indices.push_back (keypoint_index);
    }
  }
}
Beispiel #3
0
void SIFT::operator()(InputArray _image, InputArray _mask,
                      vector<KeyPoint>& keypoints,
                      OutputArray _descriptors,
                      bool useProvidedKeypoints) const
{
    int firstOctave = -1, actualNOctaves = 0, actualNLayers = 0;
    Mat image = _image.getMat(), mask = _mask.getMat();

    if( image.empty() || image.depth() != CV_8U )
        CV_Error( CV_StsBadArg, "image is empty or has incorrect depth (!=CV_8U)" );

    if( !mask.empty() && mask.type() != CV_8UC1 )
        CV_Error( CV_StsBadArg, "mask has incorrect type (!=CV_8UC1)" );

    if( useProvidedKeypoints )
    {
        firstOctave = 0;
        int maxOctave = INT_MIN;
        for( size_t i = 0; i < keypoints.size(); i++ )
        {
            int octave, layer;
            float scale;
            unpackOctave(keypoints[i], octave, layer, scale);
            firstOctave = std::min(firstOctave, octave);
            maxOctave = std::max(maxOctave, octave);
            actualNLayers = std::max(actualNLayers, layer-2);
        }

        firstOctave = std::min(firstOctave, 0);
        CV_Assert( firstOctave >= -1 && actualNLayers <= nOctaveLayers );
        actualNOctaves = maxOctave - firstOctave + 1;
    }

    Mat base = createInitialImage(image, firstOctave < 0, (float)sigma);
    vector<Mat> gpyr, dogpyr;
    int nOctaves = actualNOctaves > 0 ? actualNOctaves : cvRound(log( (double)std::min( base.cols, base.rows ) ) / log(2.) - 2) - firstOctave;

    //double t, tf = getTickFrequency();
    //t = (double)getTickCount();
    buildGaussianPyramid(base, gpyr, nOctaves);
    buildDoGPyramid(gpyr, dogpyr);

    //t = (double)getTickCount() - t;
    //printf("pyramid construction time: %g\n", t*1000./tf);

    if( !useProvidedKeypoints )
    {
        //t = (double)getTickCount();
        findScaleSpaceExtrema(gpyr, dogpyr, keypoints);
        KeyPointsFilter::removeDuplicated( keypoints );

        if( nfeatures > 0 )
            KeyPointsFilter::retainBest(keypoints, nfeatures);
        //t = (double)getTickCount() - t;
        //printf("keypoint detection time: %g\n", t*1000./tf);

        if( firstOctave < 0 )
            for( size_t i = 0; i < keypoints.size(); i++ )
            {
                KeyPoint& kpt = keypoints[i];
                float scale = 1.f/(float)(1 << -firstOctave);
                kpt.octave = (kpt.octave & ~255) | ((kpt.octave + firstOctave) & 255);
                kpt.pt *= scale;
                kpt.size *= scale;
            }

        if( !mask.empty() )
            KeyPointsFilter::runByPixelsMask( keypoints, mask );
    }
    else
    {
        // filter keypoints by mask
        //KeyPointsFilter::runByPixelsMask( keypoints, mask );
    }

    if( _descriptors.needed() )
    {
        //t = (double)getTickCount();
        int dsize = descriptorSize();
        _descriptors.create((int)keypoints.size(), dsize, CV_32F);
        Mat descriptors = _descriptors.getMat();

        calcDescriptors(gpyr, keypoints, descriptors, nOctaveLayers, firstOctave);
        //t = (double)getTickCount() - t;
        //printf("descriptor extraction time: %g\n", t*1000./tf);
    }
}