Например, у меня есть два изображения, где первое — обычное, а второе — с инверсией цвета (я имею в виду 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);
}
Пример градиентов.
Как видно, градиенты перевернутых и исходных изображений не противоположны
если ты отрицать входное изображение, то градиенты будут иметь противоположные направления (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:
convert -negate default.pgm negate.pgm
./sift --frames default.pgm
tail -n 1 default.frame > kpt.frame
./sift --descriptors --read-frames kpt.frame default.pgm
./sift --descriptors --read-frames kpt.frame negate.pgm
Затем визуализируйте вывод, например, с помощью 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
Ответ дельтеила верен, но мы могли бы легко изменить порядок элементов дескриптора 16 на 8 без изменения направления градиента (в основном это то же самое, но более просто для реализации)
Например, у нас есть дескриптор 2×4,
оригинал был:
[a,b
c,d
e,f
g,h]
перевернутым будет:
[g,h
e,f
c,d
a,b]