Как использовать алгоритм SIFT с инвертированным изображением

Например, у меня есть два изображения, где первое — обычное, а второе — с инверсией цвета (я имею в виду 255 — значение цвета в пикселях).

Я применил алгоритм SIFT к ним обоим, используя OpenCV и Лоу бумага, так что теперь у меня есть ключевые точки и дескрипторы каждого изображения.

Позиции KeyPoints действительно совпадают, но ориентации KeyPoints и значения Descriptors не совпадают из-за инверсии цвета.

Мне любопытно, кто-нибудь пытается решить такую ​​проблему?


К тому же
вот пример градиентов:

Я использую реализацию OpenCV C ++, используя этот учебник и модуль / nonfree / src / sift.cpp файл. Кроме того, я сделал следующий метод для просмотра градиентов:

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);
}

пример
Пример градиентов.

Как видно, градиенты перевернутых и исходных изображений не противоположны

0

Решение

если ты отрицать входное изображение, то градиенты будут иметь противоположные направления (G <- -G).

Вы должны напомнить, что дескрипторы SIFT — это в основном гистограмма градиентных ориентаций:

гистограмма градиентов

Так как градиент отрицается на перевернутом изображении, мы получаем:

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

Другими словами, если вы рассматриваете первые 8-биновые гистограммы (всего 4×4 таких гистограмм), и если вы обозначаете a, bи т.д., связанные компоненты SIFT дескрипторов, у нас есть:

  • Исходное изображение: [a, b, c, d, e, f, g, h]
  • перевернутое изображение: [e, f, g, h, a, b, c, d]

Таким образом, вы можете преобразовать SIFT-дескриптор в перевернутом изображении, поменяв компоненты на 4 размера.

Псевдо-алгоритм:

# `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. Отформатируйте оба дескриптора по 4 компонента в строке (см. Ниже)

Затем визуализируйте вывод, например, с помощью diff -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
4

Другие решения

Ответ дельтеила верен, но мы могли бы легко изменить порядок элементов дескриптора 16 на 8 без изменения направления градиента (в основном это то же самое, но более просто для реализации)

Например, у нас есть дескриптор 2×4,

оригинал был:

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

перевернутым будет:

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

По вопросам рекламы [email protected]