0

例如,我有两张图像,其中第一张是常规图像,第二张是颜色反转的(我的意思是 255 - 像素颜色值)。

我已经使用 OpenCV 和Lowe 论文将 SIFT 算法应用于它们,所以现在我有了每个图像的关键点和描述符。

关键点位置确实匹配,但关键点方向和描述符值不匹配,因为颜色反转。

我很好奇有人试图解决这样的问题吗?


此外 ,这里是渐变示例:

我正在使用教程和 modules/nonfree/src/sift.cpp 文件使用 OpenCV C++ 实现。此外,我还采用了以下方法来查看渐变:

void MINE::showKeypoints(cv::Mat image, std::vector<cv::KeyPoint> keypoints, string number)
{
    cv::Mat img;
    image.copyTo(img);

    for(int i=0;i<(int)keypoints.size();i++)
    {
        cv::KeyPoint kp = keypoints[i];

        cv::line(img, cv::Point2f(kp.pt.x ,kp.pt.y), cv::Point2f(kp.pt.x ,kp.pt.y), CV_RGB(255,0,0), 4);
        cv::line(img, cv::Point2f(kp.pt.x ,kp.pt.y), cv::Point2f(kp.pt.x+kp.size*cos(kp.angle),kp.pt.y+kp.size*sin(kp.angle)), CV_RGB(255,255,0), 1);
    }
    cv::imshow (str, img);
}

例子 渐变示例。

如您所见,倒置图像和原始图像的渐变并不相反

4

2 回答 2

4

If you negate the input image then the gradients will have opposite directions (G <- -G).

You need to remind that SIFT descriptors are basically histogram of gradient orientations:

histogram of gradients

Since the gradient is negated on the inverted image we obtain:

  • 0th arrow => 4th arrow
  • 1st arrow => 5th arrow
  • 2nd arrow => 6th arrow
  • 3th arrow => 7th arrow

In other words if you consider the first 8-bins histogram (there are 4x4 such histograms in total), and if you denote a, b, etc the related SIFT descriptors components, we have:

  • original image: [a, b, c, d, e, f, g, h]
  • inverted image: [e, f, g, h, a, b, c, d]

So you can convert the inverted image SIFT descriptor by swapping the components by 4-sized packs.

Pseudo-algorithm:

# `sift` is the 128-sized array that represents the descriptor
NCELLS = 16
NORI   = 8

0.upto(NCELLS - 1) do |cell|
  offset = cell * NORI
  offset.upto(offset + NORI/2 - 1) do |i|
    sift.swap!(i, i + NORI/2)
  end
end

Here's how to verify this with vlfeat:

  1. Negate the default image: convert -negate default.pgm negate.pgm
  2. Extract keypoints on default image: ./sift --frames default.pgm
  3. Select the first keypoint: tail -n 1 default.frame > kpt.frame
  4. Describe it with the default image: ./sift --descriptors --read-frames kpt.frame default.pgm
  5. Describe it with the negated image: ./sift --descriptors --read-frames kpt.frame negate.pgm
  6. Format both descriptors with 4 components per line (see below)

Then visualize the output with e.g. diff -u or opendiff: the lines are swapped 2-by-2 as expected.

cat default.descr | ruby -e\
'STDIN.read.split(" ").each_slice(4) {|s| p s}'\
> default.out

cat negate.descr | ruby -e\
'STDIN.read.split(" ").each_slice(4) {|s| p s}'\
> negate.out
于 2013-02-23T19:25:04.827 回答
0

deltheil 的回答是正确的,但是我们可以轻松地更改 16 x 8 描述符元素的顺序而不改变梯度的方向(基本上是相同的,但实现更简单)

例如我们有 2x4 描述符,

原来是:

[a,b
c,d
e,f
g,h]

倒置将是:

[g,h
e,f
c,d
a,b]
于 2013-03-07T05:38:36.820 回答