Обнаружение ключевых точек
Видеоурок 16 - Обнаружение и сохранение ключевых точек: https://singtown.com/learn/50021/
Сравнение сопоставления с шаблоном и обнаружения ключевых точек:
Сопоставление с шаблоном (find_temolate) использует алгоритм ncc, который может сопоставлять только шаблоны, практически совпадающие по размеру и углу с изображением-шаблоном. Ограничения здесь довольно существенные. Если целевой узор в поле зрения немного больше или меньше изображения-шаблона, сопоставление может оказаться неудачным.
Сопоставление с шаблоном подходит для ситуаций, когда расстояние между камерой и целевым объектом фиксировано и динамическое перемещение не требуется. Например, оно подходит для обнаружения конкретных объектов на сборочной линии, но не подходит для слежения движущейся тележки за волейбольным мячом (поскольку расстояние между движущимся мячом и камерой меняется, размер мяча в кадре камеры будет изменяться и не будет в точности совпадать с изображением-шаблоном).
Для сопоставления в нескольких ракурсах и масштабах можно попробовать сохранить несколько шаблонов и использовать Многошаблонное сопоставление.
Обнаружение ключевых точек (find_keypoint): если программа только что запущена, процедура извлекает первое изображение как признак целевого объекта, и kpts1 сохраняет признак целевого объекта. По умолчанию будет выполняться сопоставление в нескольких масштабах и углах целевого признака, а не только с тем размером и углом, которые были сохранены изначально. Это более гибко, чем сопоставление с шаблоном, и не требует сохранения нескольких изображений-шаблонов, как в многошаблонном сопоставлении.
При обнаружении ключевых точек также можно заранее сохранить целевые признаки. Раньше это не рекомендовалось, поскольку помехи от окружающего освещения и другие причины могли приводить к тому, что признаки различались при каждом запуске программы из-за разного освещения, и степень совпадения снижалась. Однако в последней версии прошивки была добавлена регулировка экспозиции, баланса белого и значения автоматического усиления. Значения экспозиции и баланса белого можно задать вручную, что относительно снижает влияние освещения. Вы также можете попробовать заранее сохранить целевые признаки.
Обнаружение ключевых точек
Эта процедура — 09-feature-Detection-keypoints.py.\ Она использует алгоритм FAST/AGAST для извлечения признаков и слежения за целью и поддерживает только изображения в градациях серого.
Примечание: в этой процедуре объект, появившийся в первые десять секунд работы программы, будет принят за целевой признак. Разместите целевой объект в центре камеры в начале работы программы и удерживайте до появления угловых точек признака — это подтвердит, что целевой признак был опознан и зафиксирован.
Если в процессе сопоставления на экране появляются крест и прямоугольная рамка, это означает, что сопоставление прошло успешно.
# Пример обнаружения определённого объекта с помощью ключевых точек.
# Покажите объект камере, затем запустите этот скрипт. Набор ключевых точек
# будет извлечён один раз, а затем отслеживаться в последующих кадрах. Если
# вам нужен новый набор ключевых точек, перезапустите скрипт.
# Примечание: см. документацию для настройки find_keypoints и match_keypoints.
import csi, time, image
csi0 = csi.CSI()
# Reset sensor
csi0.reset()
# Sensor settings
csi0.framesize(csi.VGA)
csi0.window((320, 240))
csi0.pixformat(csi.GRAYSCALE)
csi0.snapshot(time = 2000)
csi0.auto_gain(False)
#рисуем ключевые точки
def draw_keypoints(img, kpts):
if kpts:
print(kpts)
img.draw_keypoints(kpts)
img = csi0.snapshot()
time.sleep_ms(1000)
kpts1 = None
#kpts1 сохраняет признак целевого объекта, признак можно импортировать из файла, но это не рекомендуется.
#kpts1 = image.load_descriptor("/desc.orb")
#img = csi0.snapshot()
#draw_keypoints(img, kpts1)
clock = time.clock()
while (True):
clock.tick()
img = csi0.snapshot()
if (kpts1 == None):
#если программа только запустилась, извлекаем самое первое изображение как признак целевого объекта, kpts1 сохраняет признак целевого объекта
#по умолчанию будет сопоставляться несколько масштабов целевого признака, а не только тот размер, при котором признак был сохранён, это гибче, чем сопоставление с шаблоном.
# NOTE: By default find_keypoints returns multi-scale keypoints extracted from an image pyramid.
kpts1 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2)
#image.find_keypoints(roi=Auto, threshold=20, normalized=False, scale_factor=1.5, max_keypoints=100, corner_detector=CORNER_AGAST)
#roi обозначает распознаваемую область, это кортеж (x,y,w,h), по умолчанию совпадает с размером framesize.
#threshold - это порог от 0 до 255, используемый для управления количеством угловых точек, обнаруживаемых при поиске ключевых точек. При использовании детектора AGAST по умолчанию этот порог составляет примерно 20. При использовании детектора FAST этот порог составляет примерно 60~80. Чем ниже порог, тем больше угловых точек будет получено.
#normalized - логическое значение, по умолчанию False, позволяет сопоставлять целевой признак в нескольких размерах (это гибче, чем сопоставление с шаблоном ncc). Если задать True, многомасштабное сопоставление ключевых точек отключается, сопоставляется только один размер целевого признака (аналогично сопоставлению с шаблоном), но скорость вычислений будет выше.
#scale_factor - число с плавающей точкой больше 1.0. Чем выше это значение, тем быстрее скорость обнаружения, но точность сопоставления снижается. Обычно оптимальным считается диапазон 1.35~1.5.
#max_keypoints - максимальное количество ключевых точек, которое можно извлечь для объекта. Если у объекта слишком много ключевых точек и это переполняет оперативную память, уменьшите это значение.
#corner_detector - алгоритм, используемый для обнаружения ключевых точек, по умолчанию алгоритм AGAST. Алгоритм FAST быстрее, но точность снижается.
draw_keypoints(img, kpts1)
#рисуем текущий целевой признак
else:
#при сопоставлении с самым первым целевым признаком по умолчанию задаём normalized=True, сопоставляется только один размер целевого признака.
# NOTE: When extracting keypoints to match the first descriptor, we use normalized=True to extract
# keypoints from the first scale only, which will match one of the scales in the first descriptor.
kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)
#если целевой объект обнаружен
if (kpts2):
#сопоставляем сходство текущего найденного признака с исходным целевым признаком
match = image.match_descriptor(kpts1, kpts2, threshold=85)
#image.match_descriptor(descritor0, descriptor1, threshold=70, filter_outliers=False). Эта функция возвращает объект kptmatch.
#порог threshold задаёт точность сопоставления, используется для отсеивания неоднозначных совпадений. Чем меньше это значение, тем выше точность. Диапазон порога 0~100, по умолчанию 70
#filter_outliers по умолчанию отключён.
#match.count - примерное количество совпавших ключевых точек между kpt1 и kpt2.
#если больше 10, это подтверждает сходство двух признаков, сопоставление успешно.
if (match.count>10):
# If we have at least n "good matches"
# Draw bounding rectangle and cross.
#рисуем крест и прямоугольную рамку в центре найденного целевого признака.
img.draw_rectangle(match.rect)
img.draw_cross((match.cx, match.cy), size=10)
#match.theta - угол поворота найденного целевого объекта относительно исходного целевого объекта.
print(kpts2, "matched:%d dt:%d"%(match.count, match.theta))
#рисовать угловые точки признака функцией draw_keypoints не рекомендуется.
# NOTE: uncomment if you want to draw the keypoints
#img.draw_keypoints(kpts2, size=KEYPOINTS_SIZE, matched=True)
# Draw FPS
#выводим частоту кадров.
img.draw_string((0, 0), "FPS:%.2f"%(clock.fps()))
Эффект работы программы:

