image-patches-absolute-rotation-scale.py
# 本作品采用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的幂,
# 这会降低算法结果的实用性。请
# 使用像B128X128或B128X64(快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
BLOCK_W = 16 # pow2
BLOCK_H = 16 # pow2
csi0 = csi.CSI()
csi0.reset() # 重置并初始化传感器。
csi0.pixformat(csi.GRAYSCALE) # 将像素格式设置为灰度
csi0.framesize((128, 128)) # 将帧大小设置为128x128...(或64x64)...
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() # 拍照并返回图像。
for y in range(0, csi0.height(), BLOCK_H):
for x in range(0, csi0.width(), BLOCK_W):
# 在此示例中,我们从不更新旧图像,以便测量绝对变化。
displacement = extra_fb.find_displacement(
img,
logpolar=True,
roi=(x, y, BLOCK_W, BLOCK_H),
template_roi=(x, y, BLOCK_W, BLOCK_H),
)
# 低于0.1左右(因情况而异)时,结果就只是噪声了。
if displacement.response > 0.1:
rotation_change = displacement.rotation
zoom_amount = displacement.scale
pixel_x = (
x
+ (BLOCK_W // 2)
+ int(math.sin(rotation_change) * zoom_amount * (BLOCK_W // 4))
)
pixel_y = (
y
+ (BLOCK_H // 2)
+ int(math.cos(rotation_change) * zoom_amount * (BLOCK_H // 4))
)
img.draw_line(
(x + BLOCK_W // 2, y + BLOCK_H // 2, pixel_x, pixel_y), color=255
)
else:
img.draw_line(
(
x + BLOCK_W // 2,
y + BLOCK_H // 2,
x + BLOCK_W // 2,
y + BLOCK_H // 2,
),
color=0,
)
print(clock.fps())