Детектор признаков и дескриптор для изображений с низким разрешением
Я работаю с низкими разрешениями (VGA) и jpg-сжатыми последовательностями изображений для визуальной навигации на мобильном роботе. В настоящее время я использую SURF для обнаружения ключевых точек и извлечения дескрипторов из изображений, а FLANN для их отслеживания. Я получаю 4000-5000 объектов на изображение, и обычно выполняется 350-450 совпадений на пару последовательных изображений перед применением RANSAC (что обычно уменьшает количество совпадений на 20%)
Я пытаюсь увеличить количество (и качество) матчей. Я пробовал два других детектора: SIFT и ORB. SIFT заметно увеличивает количество функций (на 35% больше отслеживаемых функций, в целом), но работает намного медленнее. ORB извлекает примерно столько же функций, сколько SURF, но производительность сопоставления намного ниже (в лучшем случае ~100 совпадений). Моя реализация в opencv ORB:
cv::ORB orb = cv::ORB(10000, 1.2f, 8, 31);
orb(frame->img, cv::Mat(), im_keypoints, frame->descriptors);
frame->descriptors.convertTo(frame->descriptors, CV_32F); //so that is the same type as m_dists
И тогда, при сопоставлении:
cv::Mat m_indices(descriptors1.rows, 2, CV_32S);
cv::Mat m_dists(descriptors1.rows, 2, CV_32F);
cv::flann::Index flann_index(descriptors2, cv::flann::KDTreeIndexParams(6));
flann_index.knnSearch(descriptors1, m_indices, m_dists, 2, cv::flann::SearchParams(64) );
Каковы лучшие функции детектора и экстрактора при работе с изображениями с низким разрешением и шумом? Должен ли я изменить какой-либо параметр в FLANN в зависимости от используемого детектора функций?
РЕДАКТИРОВАТЬ:
Я выкладываю несколько фотографий с довольно простой последовательностью для отслеживания. Картинки, как я отдам их методам детектора признаков. Они были предварительно обработаны для устранения некоторого шума (посредством cv::bilateralFilter()
)
3 ответа
Во многих случаях пирамидальный метод на основе оптического потока Лукаса Канаде является хорошим выбором. метод имеет некоторые ограничения, например, большие изменения в освещении. Если вы используете большое окно 21x21 или больше, трекер должен быть более устойчивым к шуму. Вы можете получить функции для отслеживания с помощью вашего детектора функций SIFT,SURF,FAST или GFT или инициализировать их как обычную сетку выборки. Это дает вам преимущество регулярных выборок информации о движении с вашей сцены.
Я работаю с функцией обнаружения функций ORB уже несколько месяцев. Я не обнаружил проблем с самим ORB, хотя авторы говорят о тонкой настройке некоторых параметров, чтобы он работал лучше.
https://github.com/wher0001/Image-Capture-and-Processing
Когда я запускаю ORB, используя ваши картинки и стандартную сортировку по расстоянию, я получаю следующую картинку, которая, очевидно, имеет несколько плохих совпадений. ORB Matching - стандартная сортировка
Я всегда устанавливаю большое количество nfeatures (5000) и начинаю оттуда.По умолчанию это 500, что я и использовал для этих картинок. Оттуда вы можете либо изменить порядок сортировки, как я здесь показал, либо уменьшить число nfeatures, либо даже просто использовать это максимальное число совпадений X.
import numpy as np
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread("c:/Users/rwheatley/Desktop/pS8zi.jpg")
img2 = cv2.imread("c:/Users/rwheatley/Desktop/vertrk.jpg")
grey1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
grey2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# Initiate ORB detector
orb = cv2.ORB_create(nfeatures=5000)
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(grey1,None)
kp2, des2 = orb.detectAndCompute(grey2,None)
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
# Draw first 10 matches.
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches,None,flags=2)
print(len(matches))
plt.imshow(img3),plt.show()
Затем я переключаюсь на несколько различных методов, которые я считаю полезными при использовании (извините за термин) паршивой веб-камеры Dell. ORB с knnMatching
import numpy as np
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread("c:/Users/rwheatley/Desktop/pS8zi.jpg")
img2 = cv2.imread("c:/Users/rwheatley/Desktop/vertrk.jpg")
grey1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
grey2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# Initiate ORB detector
orb = cv2.ORB_create(nfeatures=5000)
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(grey1,None)
kp2, des2 = orb.detectAndCompute(grey2,None)
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < 0.75*n.distance:
good.append([m])
# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)
print(len(matches))
plt.imshow(img3),plt.show()
Существует третий тип соответствия, который в настоящее время нарушен даже в последней версии OpenCV. Фланн на основе соответствия. Когда это будет исправлено, я предлагаю вам переключиться на это или просто применить некоторые смарты к изображению.
Например, если вы добавляете гироскопы в систему, вы можете выбросить совпадения за пределы окна, созданного путем сокращения окна поиска.
Если у вас есть контроль над функцией, которую вы отслеживаете, вы можете использовать их в инварианте вращения и использовать корреляцию.