Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

duplicate sift keypoints in a single image

i'm using opencv2.3.1 to detect SIFT keypoints in an image. But i find that in the detection result, there are duplicate points. i.e., there are two keypoints with the same coordinates(in pixel), but their corresponding descriptors are very different. The following code shows the SIFT extraction procedure. I think people should be familiar with the used "box.png". So anyone who is interested can try the following code and see if you have the same problem with me.

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"
#include <iostream>
int main( )
{
cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create( "SIFT" );
cv::Ptr<cv::DescriptorExtractor> extractor = cv::DescriptorExtractor::create("SIFT" );
cv::Mat im = cv::imread("box.png", CV_LOAD_IMAGE_COLOR );
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
detector->detect( im, keypoints);
extractor->compute( im,keypoints,descriptors);
int duplicateNum = 0;
for (int i=0;i<keypoints.size();i++)
{
    for (int j=i+1;j<keypoints.size();j++)
    {
        float dist = abs((keypoints[i].pt.x-keypoints[j].pt.x))+abs((keypoints[i].pt.y-keypoints[j].pt.y));
        if (dist == 0)
        {
            cv::Mat descriptorDiff = descriptors.row(i)-descriptors.row(j);
            double diffNorm = cv::norm(descriptorDiff);
            std::cout<<"keypoint "<<i<<" equal to keypoint "<<j<<" descriptor distance "<<diffNorm<<std::endl;
            duplicateNum++;
        }
    }
}
std::cout<<"Total keypoint: "<<keypoints.size()<<", duplicateNum: "<<duplicateNum<<std::endl;

return 1;

}

like image 969
user1427630 Avatar asked May 31 '12 06:05

user1427630


1 Answers

Hope to help you understand why.

The magnitude and orientation is calculated for all pixels around the keypoint. Then, A histogram is created for this. In this histogram, the 360 degrees of orientation are broken into 36 bins (each 10 degrees). Lets say the gradient direction at a certain point (in the “orientation collection region”) is 18.759 degrees, then it will go into the 10-19 degree bin. And the “amount” that is added to the bin is proportional to the magnitude of gradient at that point. Once you’ve done this for all pixels around the keypoint, the histogram will have a peak at some point.

Suppose, you see the histogram peaks at 20-29 degrees. So, the keypoint is assigned orientation 3 (the third bin)

Also, any peaks above 80% of the highest peak are converted into a new keypoint. This new keypoint has the same location and scale as the original. But it’s orientation is equal to the other peak.

So, orientation can split up one keypoint into multiple keypoints.

Great reference about SIFT: http://aishack.in/tutorials/sift-scale-invariant-feature-transform-introduction/

like image 79
vancexu Avatar answered Sep 29 '22 21:09

vancexu