absolute-rotation-scale.py
# Эта работа лицензирована по лицензии MIT.
# Copyright (c) 2013-2023 OpenMV LLC. All rights reserved.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Абсолютный оптический поток: поворот/масштаб
#
# Этот пример демонстрирует использование камеры OpenMV Cam для измерения
# поворота/масштаба путём сравнения текущего и предыдущего
# изображений друг с другом. Обратите внимание, что обрабатывается только поворот/масштаб
# — а не смещение по X и Y в этом режиме.
#
# Для эффективного запуска этой демонстрации закрепите камеру OpenMV Cam на устойчивом
# основании и МЕДЛЕННО вращайте камеру вокруг объектива, а также перемещайте камеру
# вперёд/назад, чтобы увидеть изменение чисел.
# То есть изменения только по направлению Z.
#
# ОБРАТИТЕ ВНИМАНИЕ: при использовании
# find_displacement() необходимо использовать небольшое разрешение, кратное степени двойки. Это связано с тем, что в основе алгоритма лежит
# метод, называемый фазовой корреляцией, который выполняет сравнение изображений
# с использованием БПФ. Разрешение, не являющееся степенью двойки, требует дополнения до степени
# двойки, что снижает полезность результатов алгоритма. Пожалуйста,
# используйте разрешение вроде B64X64 или B64X32 (в 2 раза быстрее).
#
# Ваша камера OpenMV Cam поддерживает разрешения, кратные степени двойки: 64x32, 64x64,
# 128x64 и 128x128. Если вам нужно разрешение 32x32, вы можете получить его,
# выполнив "img.scale(x_scale=0.5, y_scale=0.5, hint=image.AREA)" на изображении 64x64.
import csi
import image
import time
import math
csi0 = csi.CSI()
csi0.reset() # Сброс и инициализация датчика.
csi0.pixformat(csi.RGB565) # Установить формат пикселей RGB565 (или GRAYSCALE)
csi0.framesize((64, 64)) # Установите размер кадра 64x64... (или 64x32)...
csi0.snapshot(time=2000) # Подождать, пока настройки вступят в силу.
clock = time.clock() # Создать объект clock для отслеживания FPS.
# Создайте второй буфер кадра в куче.
extra_fb = image.Image(csi0.width(), csi0.height(), csi0.pixformat())
extra_fb.draw_image(csi0.snapshot())
while True:
clock.tick() # Отслеживание количества миллисекунд, прошедших между snapshots().
img = csi0.snapshot() # Сделать снимок и вернуть изображение.
# Этот алгоритм сложно протестировать без идеального стенда... Поэтому вот небольшая хитрость, чтобы убедиться, что он работает.
# Задайте ниже значение z_rotation, и вы должны увидеть, что выходное значение r будет равно ему.
if 0:
expected_rotation = 20.0
img.rotation_corr(z_rotation=expected_rotation)
# Этот алгоритм сложно протестировать без идеального стенда... Поэтому вот небольшая хитрость, чтобы убедиться, что он работает.
# Задайте ниже значение zoom, и вы должны увидеть, что выходное значение z будет равно ему.
if 0:
expected_zoom = 0.8
img.rotation_corr(zoom=expected_zoom)
# В этом примере старое изображение никогда не обновляется, чтобы измерять абсолютное изменение.
displacement = extra_fb.find_displacement(img, logpolar=True)
# Результаты смещения зашумлены без фильтрации, поэтому мы жертвуем некоторой точностью.
rotation_change = int(math.degrees(displacement.rotation) * 5) / 5.0
zoom_amount = displacement.scale
if (
displacement.response > 0.1
): # Ниже примерно 0.1 (может отличаться) результаты — это просто шум.
print(
"{0:+f}r {1:+f}z {2} {3} FPS".format(
rotation_change, zoom_amount, displacement.response, clock.fps()
)
)
else:
print(clock.fps())