surf_turtoise.patch

turtoiseSVN patch to surf.cpp - Yvonnic MM, 2011-06-07 04:06 pm

Download (10.8 kB)

 
surf.cpp (copie de travail)
114 114
    CvSURFParams params;
115 115
    params.hessianThreshold = threshold;
116 116
    params.extended = extended;
117
    params.upright = 0;
117 118
    params.nOctaves = 4;
118 119
    params.nOctaveLayers = 2;
119 120
    return params;
......
575 576
                DW[i*PATCH_SZ+j] = G_desc.at<float>(i,0) * G_desc.at<float>(j,0);
576 577
        }
577 578
    }
578

  
579 579
    void operator()(const BlockedRange& range) const
580 580
    {
581 581
        /* X and Y gradient wavelet data */
......
630 630
                kp->size = -1;
631 631
                continue;
632 632
            }
633
            icvResizeHaarPattern( dx_s, dx_t, NX, 4, grad_wav_size, sum->cols );
634
            icvResizeHaarPattern( dy_s, dy_t, NY, 4, grad_wav_size, sum->cols );
635
            for( kk = 0, nangle = 0; kk < nOriSamples; kk++ )
636
            {
637
                const int* ptr;
638
                float vx, vy;
639
                x = cvRound( center.x + apt[kk].x*s - (float)(grad_wav_size-1)/2 );
640
                y = cvRound( center.y + apt[kk].y*s - (float)(grad_wav_size-1)/2 );
641
                if( (unsigned)y >= (unsigned)(sum->rows - grad_wav_size) ||
642
                   (unsigned)x >= (unsigned)(sum->cols - grad_wav_size) )
633

  
634
            float descriptor_dir;
635
            if (params->upright == 0) {
636

  
637
                icvResizeHaarPattern( dx_s, dx_t, NX, 4, grad_wav_size, sum->cols );
638
                icvResizeHaarPattern( dy_s, dy_t, NY, 4, grad_wav_size, sum->cols );
639
                for( kk = 0, nangle = 0; kk < nOriSamples; kk++ )
640
                {
641
                    const int* ptr;
642
                    float vx, vy;
643
                    x = cvRound( center.x + apt[kk].x*s - (float)(grad_wav_size-1)/2 );
644
                    y = cvRound( center.y + apt[kk].y*s - (float)(grad_wav_size-1)/2 );
645
                    if( (unsigned)y >= (unsigned)(sum->rows - grad_wav_size) ||
646
                        (unsigned)x >= (unsigned)(sum->cols - grad_wav_size) )
647
                        continue;
648
                    ptr = sum_ptr + x + y*sum_cols;
649
                    vx = icvCalcHaarPattern( ptr, dx_t, 2 );
650
                    vy = icvCalcHaarPattern( ptr, dy_t, 2 );
651
                    X[nangle] = vx*aptw[kk]; Y[nangle] = vy*aptw[kk];
652
                    nangle++;
653
                }
654
                if ( nangle == 0 )
655
                {
656
                    /* No gradient could be sampled because the keypoint is too
657
                    * near too one or more of the sides of the image. As we
658
                    * therefore cannot find a dominant direction, we skip this
659
                    * keypoint and mark it for later deletion from the sequence. */
660
                    kp->size = -1;
643 661
                    continue;
644
                ptr = sum_ptr + x + y*sum_cols;
645
                vx = icvCalcHaarPattern( ptr, dx_t, 2 );
646
                vy = icvCalcHaarPattern( ptr, dy_t, 2 );
647
                X[nangle] = vx*aptw[kk]; Y[nangle] = vy*aptw[kk];
648
                nangle++;
649
            }
650
            if ( nangle == 0 )
651
            {
652
                /* No gradient could be sampled because the keypoint is too
653
                 * near too one or more of the sides of the image. As we
654
                 * therefore cannot find a dominant direction, we skip this
655
                 * keypoint and mark it for later deletion from the sequence. */
656
                kp->size = -1;
657
                continue;
658
            }
659
            matX.cols = matY.cols = _angle.cols = nangle;
660
            cvCartToPolar( &matX, &matY, 0, &_angle, 1 );
662
                }
663
                matX.cols = matY.cols = _angle.cols = nangle;
664
                cvCartToPolar( &matX, &matY, 0, &_angle, 1 );
661 665

  
662
            float bestx = 0, besty = 0, descriptor_mod = 0;
663
            for( i = 0; i < 360; i += ORI_SEARCH_INC )
664
            {
665
                float sumx = 0, sumy = 0, temp_mod;
666
                for( j = 0; j < nangle; j++ )
666
                float bestx = 0, besty = 0, descriptor_mod = 0;
667
                for( i = 0; i < 360; i += ORI_SEARCH_INC )
667 668
                {
668
                    int d = std::abs(cvRound(angle[j]) - i);
669
                    if( d < ORI_WIN/2 || d > 360-ORI_WIN/2 )
669
                    float sumx = 0, sumy = 0, temp_mod;
670
                    for( j = 0; j < nangle; j++ )
670 671
                    {
671
                        sumx += X[j];
672
                        sumy += Y[j];
672
                        int d = std::abs(cvRound(angle[j]) - i);
673
                        if( d < ORI_WIN/2 || d > 360-ORI_WIN/2 )
674
                        {
675
                            sumx += X[j];
676
                            sumy += Y[j];
677
                        }
673 678
                    }
679
                    temp_mod = sumx*sumx + sumy*sumy;
680
                    if( temp_mod > descriptor_mod )
681
                    {
682
                        descriptor_mod = temp_mod;
683
                        bestx = sumx;
684
                        besty = sumy;
685
                    }
674 686
                }
675
                temp_mod = sumx*sumx + sumy*sumy;
676
                if( temp_mod > descriptor_mod )
677
                {
678
                    descriptor_mod = temp_mod;
679
                    bestx = sumx;
680
                    besty = sumy;
681
                }
687

  
688
                descriptor_dir = cvFastArctan( besty, bestx );
689
                kp->dir = descriptor_dir;
690
            } else {
691
                descriptor_dir = 0;
692
                kp->dir = 0;
682 693
            }
683
            float descriptor_dir = cvFastArctan( besty, bestx );
684
            kp->dir = descriptor_dir;
685 694
            if( !descriptors )
686 695
                continue;
687 696
            descriptor_dir *= (float)(CV_PI/180);
......
689 698
            int win_size = (int)((PATCH_SZ+1)*s);
690 699
            CV_Assert( winbuf->cols >= win_size*win_size );
691 700
            CvMat win = cvMat(win_size, win_size, CV_8U, winbuf->data.ptr);
692
            float sin_dir = sin(descriptor_dir);
693
            float cos_dir = cos(descriptor_dir) ;
694 701

  
695
            /* Subpixel interpolation version (slower). Subpixel not required since
696
             the pixels will all get averaged when we scale down to 20 pixels */
697
            /*
698
             float w[] = { cos_dir, sin_dir, center.x,
699
             -sin_dir, cos_dir , center.y };
700
             CvMat W = cvMat(2, 3, CV_32F, w);
701
             cvGetQuadrangleSubPix( img, &win, &W );
702
             */
702
            if (params->upright == 0) {
703 703

  
704
            /* Nearest neighbour version (faster) */
705
            float win_offset = -(float)(win_size-1)/2;
706
            float start_x = center.x + win_offset*cos_dir + win_offset*sin_dir;
707
            float start_y = center.y - win_offset*sin_dir + win_offset*cos_dir;
708
            uchar* WIN = win.data.ptr;
709
            for( i = 0; i < win_size; i++, start_x += sin_dir, start_y += cos_dir )
710
            {
711
                float pixel_x = start_x;
712
                float pixel_y = start_y;
713
                for( j = 0; j < win_size; j++, pixel_x += cos_dir, pixel_y -= sin_dir )
704
                float sin_dir = sin(descriptor_dir);
705
                float cos_dir = cos(descriptor_dir) ;
706

  
707
                /* Subpixel interpolation version (slower). Subpixel not required since
708
                the pixels will all get averaged when we scale down to 20 pixels */
709
                /*  
710
                float w[] = { cos_dir, sin_dir, center.x,
711
                -sin_dir, cos_dir , center.y };
712
                CvMat W = cvMat(2, 3, CV_32F, w);
713
                cvGetQuadrangleSubPix( img, &win, &W );
714
                */
715

  
716
                /* Nearest neighbour version (faster) */
717
                float win_offset = -(float)(win_size-1)/2;
718
                float start_x = center.x + win_offset*cos_dir + win_offset*sin_dir;
719
                float start_y = center.y - win_offset*sin_dir + win_offset*cos_dir;
720
                uchar* WIN = win.data.ptr;
721
                for( i = 0; i < win_size; i++, start_x += sin_dir, start_y += cos_dir )
714 722
                {
715
                    int x = std::min(std::max(cvRound(pixel_x), 0), img->cols-1);
716
                    int y = std::min(std::max(cvRound(pixel_y), 0), img->rows-1);
717
                    WIN[i*win_size + j] = img->data.ptr[y*img->step + x];
723
                    float pixel_x = start_x;
724
                    float pixel_y = start_y;
725
                    for( j = 0; j < win_size; j++, pixel_x += cos_dir, pixel_y -= sin_dir )
726
                    {
727
                        int x = std::min(std::max(cvRound(pixel_x), 0), img->cols-1);
728
                        int y = std::min(std::max(cvRound(pixel_y), 0), img->rows-1);
729
                        WIN[i*win_size + j] = img->data.ptr[y*img->step + x];
730
                    }
718 731
                }
732
            } else {
733
                /* extract rect - slightly optimized version of the code above
734
                   TODO: find faster code, as this is simply an extract rect operation, 
735
                         e.g. by using cvGetSubRect, problem is the border processing */
736
                
737
                float win_offset = -(float)(win_size-1)/2;
738
                int start_x = cvRound(center.x + win_offset);
739
                int start_y = cvRound(center.y + win_offset);
740
                uchar* WIN = win.data.ptr;
741
                for( i=0; i<win_size; i++, start_y++ )
742
                {
743
                    int pixel_x = start_x;
744
                    for( j=0; j<win_size; j++, pixel_x++ )
745
                    {
746
                        x = MAX( pixel_x, 0 );
747
                        y = MAX( start_y, 0 );
748
                        x = MIN( x, img->cols-1 );
749
                        y = MIN( y, img->rows-1 );
750
                        WIN[i*win_size + j] = img->data.ptr[y*img->step+x];
751
                    }
752
                }               
719 753
            }
720

  
721 754
            /* Scale the window to size PATCH_SZ so each pixel's size is s. This
722 755
             makes calculating the gradients with wavelets of size 2s easy */
723 756
            cvResize( &win, &_patch, CV_INTER_AREA );
......
886 919
        cv::parallel_for(cv::BlockedRange(0, N),
887 920
                     cv::SURFInvoker(&params, keypoints, descriptors, img, sum) );
888 921
#else
889
	cv::SURFInvoker invoker(&params, keypoints, descriptors, img, sum);
890
	invoker(cv::BlockedRange(0, N));
922
	    cv::SURFInvoker invoker(&params, keypoints, descriptors, img, sum);
923
	    invoker(cv::BlockedRange(0, N));
891 924
#endif
892 925
    }
893 926

  
......
924 957
{
925 958
    hessianThreshold = 100;
926 959
    extended = 1;
960
    upright = 0;
927 961
    nOctaves = 4;
928 962
    nOctaveLayers = 2;
929 963
}
930 964

  
931
SURF::SURF(double _threshold, int _nOctaves, int _nOctaveLayers, bool _extended)
965
SURF::SURF(double _threshold, int _nOctaves, int _nOctaveLayers, bool _extended, bool _upright)
932 966
{
933 967
    hessianThreshold = _threshold;
934 968
    extended = _extended;
969
    upright = _upright;
935 970
    nOctaves = _nOctaves;
936 971
    nOctaveLayers = _nOctaveLayers;
937 972
}