0

たとえば、2 つの画像があります。最初の画像は通常の画像で、2 番目の画像は色が反転したものです (つまり、255 - ピクセルの色の値)。

OpenCV とLowe paperを使用して両方に SIFT アルゴリズムを適用したので、各画像のキー ポイントと記述子が得られました。

KeyPoints の位置は一致しますが、KeyPoints の向きと Descriptors の値は一致しません。これは、色が反転しているためです。

誰かがそのような問題を解決しようとしていますか?


さらに 、グラデーションの例を次に示します。

このチュートリアルと 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

入力画像を無効にすると、勾配の方向が反対になります( G <- -G)。

SIFT 記述子は基本的に勾配方向のヒストグラムであることを思い出してください。

勾配のヒストグラム

反転した画像では勾配が無効になっているため、次の結果が得られます。

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

言い換えると、最初の 8 ビンのヒストグラム (合計で 4x4 のヒストグラムがあります) を考慮し、関連する SIFT 記述子コンポーネントをa、 、 などで表すと、次のようになります。b

  • 元の画像:[a, b, c, d, e, f, g, h]
  • 反転画像:[e, f, g, h, a, b, c, d]

したがって、コンポーネントを 4 サイズのパックで交換することにより、反転イメージ SIFT 記述子を変換できます。

疑似アルゴリズム:

# `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

vlfeatでこれを確認する方法は次のとおりです。

  1. デフォルトのイメージを否定します。convert -negate default.pgm negate.pgm
  2. デフォルト画像のキーポイントを抽出:./sift --frames default.pgm
  3. 最初のキーポイントを選択します。tail -n 1 default.frame > kpt.frame
  4. デフォルトの画像で説明します。./sift --descriptors --read-frames kpt.frame default.pgm
  5. 否定されたイメージで説明します。./sift --descriptors --read-frames kpt.frame negate.pgm
  6. 1 行あたり 4 つのコンポーネントで両方の記述子をフォーマットします (以下を参照)。

次に、出力を egdiff -uまたはで視覚化しますopendiff。期待どおり、行は 2 行 2 列でスワップされます。

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 に答える