Merge branch 'master' of https://github.com/Itseez/opencv
authorsprice <seth@planet-labs.com>
Thu, 6 Mar 2014 23:39:06 +0000 (15:39 -0800)
committersprice <seth@planet-labs.com>
Thu, 6 Mar 2014 23:39:06 +0000 (15:39 -0800)
Conflicts:
modules/features2d/include/opencv2/features2d.hpp
modules/features2d/src/freak.cpp
modules/features2d/src/stardetector.cpp

1  2 
modules/features2d/include/opencv2/features2d.hpp
modules/features2d/src/freak.cpp
modules/features2d/src/stardetector.cpp
modules/imgproc/src/sumpixels.cpp

@@@ -395,18 -403,10 +403,18 @@@ public
      };
  
  protected:
-     virtual void computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const;
+     virtual void computeImpl( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray descriptors ) const;
      void buildPattern();
 -    uchar meanIntensity( InputArray image, InputArray integral, const float kp_x, const float kp_y,
 -                         const unsigned int scale, const unsigned int rot, const unsigned int point ) const;
 +
 +    template <typename imgType, typename iiType>
-     imgType meanIntensity( const Mat& image, const Mat& integral, const float kp_x, const float kp_y,
++    imgType meanIntensity( InputArray image, InputArray integral, const float kp_x, const float kp_y,
 +                           const unsigned int scale, const unsigned int rot, const unsigned int point ) const;
 +
 +    template <typename srcMatType, typename iiMatType>
-     void computeDescriptors( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const;
++    void computeDescriptors( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray descriptors ) const;
 +
 +    template <typename srcMatType>
 +    void extractDescriptor(srcMatType *pointsValue, void ** ptr) const;
  
      bool orientationNormalized; //true if the orientation is normalized, false otherwise
      bool scaleNormalized; //true if the scale is normalized, false otherwise
@@@ -224,123 -239,8 +239,124 @@@ void FREAK::computeImpl( InputArray _im
  
      ((FREAK*)this)->buildPattern();
  
-             computeDescriptors<uchar, int>(grayImage, keypoints, descriptors);
 +    // Convert to gray if not already
 +    Mat grayImage = image;
 +//    if( image.channels() > 1 )
 +//        cvtColor( image, grayImage, COLOR_BGR2GRAY );
 +
 +    // Use 32-bit integers if we won't overflow in the integral image
 +    if ((image.depth() == CV_8U || image.depth() == CV_8S) &&
 +        (image.rows * image.cols) < 8388608 ) // 8388608 = 2 ^ (32 - 8(bit depth) - 1(sign bit))
 +    {
 +        // Create the integral image appropriate for our type & usage
 +        if (image.depth() == CV_8U)
-             computeDescriptors<char, int>(grayImage, keypoints, descriptors);
++            computeDescriptors<uchar, int>(grayImage, keypoints, _descriptors);
 +        else if (image.depth() == CV_8S)
-             computeDescriptors<uchar, double>(grayImage, keypoints, descriptors);
++            computeDescriptors<char, int>(grayImage, keypoints, _descriptors);
 +        else
 +            CV_Error( Error::StsUnsupportedFormat, "" );
 +    } else {
 +        // Create the integral image appropriate for our type & usage
 +        if ( image.depth() == CV_8U )
-             computeDescriptors<char, double>(grayImage, keypoints, descriptors);
++            computeDescriptors<uchar, double>(grayImage, keypoints, _descriptors);
 +        else if ( image.depth() == CV_8S )
-             computeDescriptors<ushort, double>(grayImage, keypoints, descriptors);
++            computeDescriptors<char, double>(grayImage, keypoints, _descriptors);
 +        else if ( image.depth() == CV_16U )
-             computeDescriptors<short, double>(grayImage, keypoints, descriptors);
++            computeDescriptors<ushort, double>(grayImage, keypoints, _descriptors);
 +        else if ( image.depth() == CV_16S )
- void FREAK::computeDescriptors( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const {
++            computeDescriptors<short, double>(grayImage, keypoints, _descriptors);
 +        else
 +            CV_Error( Error::StsUnsupportedFormat, "" );
 +    }
 +}
 +
 +template <typename srcMatType>
 +void FREAK::extractDescriptor(srcMatType *pointsValue, void ** ptr) const
 +{
 +    std::bitset<FREAK_NB_PAIRS>** ptrScalar = (std::bitset<FREAK_NB_PAIRS>**) ptr;
 +
 +    // extracting descriptor preserving the order of SSE version
 +    int cnt = 0;
 +    for( int n = 7; n < FREAK_NB_PAIRS; n += 128)
 +    {
 +        for( int m = 8; m--; )
 +        {
 +            int nm = n-m;
 +            for(int kk = nm+15*8; kk >= nm; kk-=8, ++cnt)
 +            {
 +                (*ptrScalar)->set(kk, pointsValue[descriptionPairs[cnt].i] >= pointsValue[descriptionPairs[cnt].j]);
 +            }
 +        }
 +    }
 +    --(*ptrScalar);
 +}
 +
 +#if CV_SSE2
 +template <>
 +void FREAK::extractDescriptor(uchar *pointsValue, void ** ptr) const
 +{
 +    __m128i** ptrSSE = (__m128i**) ptr;
 +
 +    // note that comparisons order is modified in each block (but first 128 comparisons remain globally the same-->does not affect the 128,384 bits segmanted matching strategy)
 +    int cnt = 0;
 +    for( int n = FREAK_NB_PAIRS/128; n-- ; )
 +    {
 +        __m128i result128 = _mm_setzero_si128();
 +        for( int m = 128/16; m--; cnt += 16 )
 +        {
 +            __m128i operand1 = _mm_set_epi8(pointsValue[descriptionPairs[cnt+0].i],
 +                                            pointsValue[descriptionPairs[cnt+1].i],
 +                                            pointsValue[descriptionPairs[cnt+2].i],
 +                                            pointsValue[descriptionPairs[cnt+3].i],
 +                                            pointsValue[descriptionPairs[cnt+4].i],
 +                                            pointsValue[descriptionPairs[cnt+5].i],
 +                                            pointsValue[descriptionPairs[cnt+6].i],
 +                                            pointsValue[descriptionPairs[cnt+7].i],
 +                                            pointsValue[descriptionPairs[cnt+8].i],
 +                                            pointsValue[descriptionPairs[cnt+9].i],
 +                                            pointsValue[descriptionPairs[cnt+10].i],
 +                                            pointsValue[descriptionPairs[cnt+11].i],
 +                                            pointsValue[descriptionPairs[cnt+12].i],
 +                                            pointsValue[descriptionPairs[cnt+13].i],
 +                                            pointsValue[descriptionPairs[cnt+14].i],
 +                                            pointsValue[descriptionPairs[cnt+15].i]);
 +
 +            __m128i operand2 = _mm_set_epi8(pointsValue[descriptionPairs[cnt+0].j],
 +                                            pointsValue[descriptionPairs[cnt+1].j],
 +                                            pointsValue[descriptionPairs[cnt+2].j],
 +                                            pointsValue[descriptionPairs[cnt+3].j],
 +                                            pointsValue[descriptionPairs[cnt+4].j],
 +                                            pointsValue[descriptionPairs[cnt+5].j],
 +                                            pointsValue[descriptionPairs[cnt+6].j],
 +                                            pointsValue[descriptionPairs[cnt+7].j],
 +                                            pointsValue[descriptionPairs[cnt+8].j],
 +                                            pointsValue[descriptionPairs[cnt+9].j],
 +                                            pointsValue[descriptionPairs[cnt+10].j],
 +                                            pointsValue[descriptionPairs[cnt+11].j],
 +                                            pointsValue[descriptionPairs[cnt+12].j],
 +                                            pointsValue[descriptionPairs[cnt+13].j],
 +                                            pointsValue[descriptionPairs[cnt+14].j],
 +                                            pointsValue[descriptionPairs[cnt+15].j]);
 +
 +            __m128i workReg = _mm_min_epu8(operand1, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
 +            workReg = _mm_cmpeq_epi8(workReg, operand2);        // emulated "not less than" for 8-bit UNSIGNED integers
 +
 +            workReg = _mm_and_si128(_mm_set1_epi16(short(0x8080 >> m)), workReg); // merge the last 16 bits with the 128bits std::vector until full
 +            result128 = _mm_or_si128(result128, workReg);
 +        }
 +        (**ptrSSE) = result128;
 +        ++(*ptrSSE);
 +    }
 +    (*ptrSSE) -= 8;
 +}
 +#endif
 +
 +template <typename srcMatType, typename iiMatType>
++void FREAK::computeDescriptors( InputArray _image, std::vector<KeyPoint>& keypoints, OutputArray _descriptors ) const {
 +
++    Mat image = _image.getMat();
      Mat imgIntegral;
 -    integral(image, imgIntegral);
 +    integral(image, imgIntegral, DataType<iiMatType>::type);
      std::vector<int> kpScaleIdx(keypoints.size()); // used to save pattern scale index corresponding to each keypoints
      const std::vector<int>::iterator ScaleIdxBegin = kpScaleIdx.begin(); // used in std::vector erase function
      const std::vector<cv::KeyPoint>::iterator kpBegin = keypoints.begin(); // used in std::vector erase function
      }
  
      // allocate descriptor memory, estimate orientations, extract descriptors
-     if( !extAll ) {
+     if( !extAll )
+     {
          // extract the best comparisons only
-         descriptors = cv::Mat::zeros((int)keypoints.size(), FREAK_NB_PAIRS/8, CV_8U);
+         _descriptors.create((int)keypoints.size(), FREAK_NB_PAIRS/8, CV_8U);
+         _descriptors.setTo(Scalar::all(0));
+         Mat descriptors = _descriptors.getMat();
 -#if CV_SSE2
 -        __m128i* ptr= (__m128i*) (descriptors.data+(keypoints.size()-1)*descriptors.step[0]);
 -#else
 -        std::bitset<FREAK_NB_PAIRS>* ptr = (std::bitset<FREAK_NB_PAIRS>*) (descriptors.data+(keypoints.size()-1)*descriptors.step[0]);
 -#endif
 -        for( size_t k = keypoints.size(); k--; )
 -        {
++
 +        void *ptr = descriptors.data+(keypoints.size()-1)*descriptors.step[0];
 +
 +        for( size_t k = keypoints.size(); k--; ) {
              // estimate orientation (gradient)
-             if( !orientationNormalized ) {
+             if( !orientationNormalized )
+             {
                  thetaIdx = 0; // assign 0° to all keypoints
                  keypoints[k].angle = 0.0;
              }
-             else {
+             else
+             {
                  // get the points intensity value in the un-rotated pattern
 -                for( int i = FREAK_NB_POINTS; i--; )
 -                {
 -                    pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], 0, i);
 +                for( int i = FREAK_NB_POINTS; i--; ) {
 +                    pointsValue[i] = meanIntensity<srcMatType, iiMatType>(image, imgIntegral,
 +                                                                          keypoints[k].pt.x, keypoints[k].pt.y,
 +                                                                          kpScaleIdx[k], 0, i);
                  }
                  direction0 = 0;
                  direction1 = 0;
                      thetaIdx -= FREAK_NB_ORIENTATION;
              }
              // extract descriptor at the computed orientation
 -            for( int i = FREAK_NB_POINTS; i--; )
 -            {
 -                pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], thetaIdx, i);
 +            for( int i = FREAK_NB_POINTS; i--; ) {
 +                pointsValue[i] = meanIntensity<srcMatType, iiMatType>(image, imgIntegral,
 +                                                                      keypoints[k].pt.x, keypoints[k].pt.y,
 +                                                                      kpScaleIdx[k], thetaIdx, i);
              }
 -#if CV_SSE2
 -            // note that comparisons order is modified in each block (but first 128 comparisons remain globally the same-->does not affect the 128,384 bits segmanted matching strategy)
 -            int cnt = 0;
 -            for( int n = FREAK_NB_PAIRS/128; n-- ; )
 -            {
 -                __m128i result128 = _mm_setzero_si128();
 -                for( int m = 128/16; m--; cnt += 16 )
 -                {
 -                    __m128i operand1 = _mm_set_epi8(
 -                        pointsValue[descriptionPairs[cnt+0].i],
 -                        pointsValue[descriptionPairs[cnt+1].i],
 -                        pointsValue[descriptionPairs[cnt+2].i],
 -                        pointsValue[descriptionPairs[cnt+3].i],
 -                        pointsValue[descriptionPairs[cnt+4].i],
 -                        pointsValue[descriptionPairs[cnt+5].i],
 -                        pointsValue[descriptionPairs[cnt+6].i],
 -                        pointsValue[descriptionPairs[cnt+7].i],
 -                        pointsValue[descriptionPairs[cnt+8].i],
 -                        pointsValue[descriptionPairs[cnt+9].i],
 -                        pointsValue[descriptionPairs[cnt+10].i],
 -                        pointsValue[descriptionPairs[cnt+11].i],
 -                        pointsValue[descriptionPairs[cnt+12].i],
 -                        pointsValue[descriptionPairs[cnt+13].i],
 -                        pointsValue[descriptionPairs[cnt+14].i],
 -                        pointsValue[descriptionPairs[cnt+15].i]);
 -
 -                    __m128i operand2 = _mm_set_epi8(
 -                        pointsValue[descriptionPairs[cnt+0].j],
 -                        pointsValue[descriptionPairs[cnt+1].j],
 -                        pointsValue[descriptionPairs[cnt+2].j],
 -                        pointsValue[descriptionPairs[cnt+3].j],
 -                        pointsValue[descriptionPairs[cnt+4].j],
 -                        pointsValue[descriptionPairs[cnt+5].j],
 -                        pointsValue[descriptionPairs[cnt+6].j],
 -                        pointsValue[descriptionPairs[cnt+7].j],
 -                        pointsValue[descriptionPairs[cnt+8].j],
 -                        pointsValue[descriptionPairs[cnt+9].j],
 -                        pointsValue[descriptionPairs[cnt+10].j],
 -                        pointsValue[descriptionPairs[cnt+11].j],
 -                        pointsValue[descriptionPairs[cnt+12].j],
 -                        pointsValue[descriptionPairs[cnt+13].j],
 -                        pointsValue[descriptionPairs[cnt+14].j],
 -                        pointsValue[descriptionPairs[cnt+15].j]);
 -
 -                    __m128i workReg = _mm_min_epu8(operand1, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
 -                    workReg = _mm_cmpeq_epi8(workReg, operand2);        // emulated "not less than" for 8-bit UNSIGNED integers
 -
 -                    workReg = _mm_and_si128(_mm_set1_epi16(short(0x8080 >> m)), workReg); // merge the last 16 bits with the 128bits std::vector until full
 -                    result128 = _mm_or_si128(result128, workReg);
 -                }
 -                (*ptr) = result128;
 -                ++ptr;
 -            }
 -            ptr -= 8;
 -#else
 -            // extracting descriptor preserving the order of SSE version
 -            int cnt = 0;
 -            for( int n = 7; n < FREAK_NB_PAIRS; n += 128)
 -            {
 -                for( int m = 8; m--; )
 -                {
 -                    int nm = n-m;
 -                    for(int kk = nm+15*8; kk >= nm; kk-=8, ++cnt)
 -                    {
 -                        ptr->set(kk, pointsValue[descriptionPairs[cnt].i] >= pointsValue[descriptionPairs[cnt].j]);
 -                    }
 -                }
 -            }
 -            --ptr;
 -#endif
 +
 +            // Extract descriptor
 +            extractDescriptor<srcMatType>(pointsValue, &ptr);
          }
      }
-     else { // extract all possible comparisons for selection
-         descriptors = cv::Mat::zeros((int)keypoints.size(), 128, CV_8U);
+     else // extract all possible comparisons for selection
+     {
+         _descriptors.create((int)keypoints.size(), 128, CV_8U);
+         _descriptors.setTo(Scalar::all(0));
+         Mat descriptors = _descriptors.getMat();
          std::bitset<1024>* ptr = (std::bitset<1024>*) (descriptors.data+(keypoints.size()-1)*descriptors.step[0]);
  
-         for( size_t k = keypoints.size(); k--; ) {
+         for( size_t k = keypoints.size(); k--; )
+         {
              //estimate orientation (gradient)
-             if( !orientationNormalized ) {
+             if( !orientationNormalized )
+             {
                  thetaIdx = 0;//assign 0° to all keypoints
                  keypoints[k].angle = 0.0;
              }
-             else {
+             else
+             {
                  //get the points intensity value in the un-rotated pattern
                  for( int i = FREAK_NB_POINTS;i--; )
 -                    pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], 0, i);
 +                    pointsValue[i] = meanIntensity<srcMatType, iiMatType>(image, imgIntegral,
 +                                                                          keypoints[k].pt.x,keypoints[k].pt.y,
 +                                                                          kpScaleIdx[k], 0, i);
  
                  direction0 = 0;
                  direction1 = 0;
  }
  
  // simply take average on a square patch, not even gaussian approx
 -uchar FREAK::meanIntensity( InputArray _image, InputArray _integral,
 -                            const float kp_x,
 -                            const float kp_y,
 -                            const unsigned int scale,
 -                            const unsigned int rot,
 -                            const unsigned int point) const
 -{
 +template <typename imgType, typename iiType>
- imgType FREAK::meanIntensity( const cv::Mat& image, const cv::Mat& integral,
++imgType FREAK::meanIntensity( InputArray _image, InputArray _integral,
 +                              const float kp_x,
 +                              const float kp_y,
 +                              const unsigned int scale,
 +                              const unsigned int rot,
 +                              const unsigned int point) const {
+     Mat image = _image.getMat(), integral = _integral.getMat();
      // get point position in image
      const PatternPoint& FreakPoint = patternLookup[scale*FREAK_NB_ORIENTATION*FREAK_NB_POINTS + rot*FREAK_NB_POINTS + point];
      const float xf = FreakPoint.x+kp_x;
@@@ -441,10 -426,10 +441,10 @@@ StarDetector::StarDetector(int _maxSize
  {}
  
  
- void StarDetector::detectImpl( const Mat& image, std::vector<KeyPoint>& keypoints, const Mat& mask ) const
+ void StarDetector::detectImpl( InputArray _image, std::vector<KeyPoint>& keypoints, InputArray _mask ) const
  {
-     Mat grayImage = image;
+     Mat image = _image.getMat(), mask = _mask.getMat(), grayImage = image;
 -    if( image.type() != CV_8U ) cvtColor( image, grayImage, COLOR_BGR2GRAY );
 +    if( image.channels() > 1 ) cvtColor( image, grayImage, COLOR_BGR2GRAY );
  
      (*this)(grayImage, keypoints);
      KeyPointsFilter::runByPixelsMask( keypoints, mask );