绝对光流旋转/缩放
# 本作品采用MIT许可证授权。
# 版权所有 (c) 2013-2023 OpenMV LLC。保留所有权利。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# 绝对光流旋转/缩放
#
# 此示例展示了如何使用您的OpenMV摄像头测量
# 旋转/缩放,方法是将当前图像与之前的图像
# 相互比较。注意此模式下仅处理旋转/缩放,
# 不处理X和Y方向的平移。
#
# 为了有效运行此演示,请将您的OpenMV摄像头安装在稳固的
# 底座上,然后缓慢地绕镜头轴旋转相机,并前后移动相机
# 以观察数值变化。
# 即仅Z方向发生变化。
#
# 注意:在使用find_displacement()时,您必须使用较小的2的幂
# 分辨率。这是因为该算法基于
# 相位相关技术,它使用FFT进行
# 图像比较。非2的幂的分辨率需要填充到2的幂,
# 这会降低算法结果的实用性。请
# 使用B64X64或B64X32(快2倍)这样的分辨率。
#
# 您的OpenMV摄像头支持64x32、64x64、
# 128x64和128x128这些2的幂分辨率。如果您需要32x32的分辨率,
# 可以在64x64图像上执行“img.scale(x_scale=0.5, y_scale=0.5, hint=image.AREA)”来创建。
import csi
import image
import time
import math
csi0 = csi.CSI()
csi0.reset() # 重置并初始化传感器。
csi0.pixformat(csi.RGB565) # 将像素格式设置为RGB565 (or GRAYSCALE)
csi0.framesize((64, 64)) # 将帧大小设置为64x64...(或64x32)...
csi0.snapshot(time=2000) # 等待设置生效。
clock = time.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())