Example: 08-RPC-Library/34-Remote-Control/image_transfer_raw_as_the_controller_device.py

# 本作品采用MIT许可证授权。
# 版权所有 (c) 2013-2023 OpenMV LLC。保留所有权利。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# 图像传输 - 作为控制器设备
#
# 此脚本旨在与运行“image_transfer_raw_as_the_remote_device.py”的另一个OpenMV Cam配对。
#
# 此脚本展示了如何将帧缓冲区从一个OpenMV Cam传输到另一个。

import image
import omv
import rpc
import sensor
import struct
import time

# 上述RPC库已安装在您的OpenMV Cam上,并提供了多个类,
# 允许您的OpenMV Cam通过CAN、I2C、SPI、UART或LAN/WLAN进行控制。

##############################################################
# 选择您希望通过其控制OpenMV Cam的接口。
##############################################################

# 取消注释以下行以设置您的OpenMV Cam以通过CAN进行控制。
#
# * message_id - 用于在CAN总线上传输数据的CAN消息(11位)。
# * bit_rate - CAN比特率。
# * sample_point - Tseg1/Tseg2比率。通常为75%。(50.0, 62.5, 75.0, 87.5等)
#
# 注意:主设备和从设备的消息ID和CAN比特率必须匹配。将主设备的CAN高连接到从设备。
#       can high and master can low to slave can lo. The can bus must be terminated with 120 ohms.
#
# 接口 = rpc.rpc_can_master(message_id=0x7FF, bit_rate=1000000, sample_point=75.0)

# 取消注释以下行以设置您的OpenMV Cam通过I2C进行控制。
#
# * slave_addr - I2C地址。
# * rate - I2C总线时钟频率。
#
# 注意:主设备和从设备地址必须匹配。将主设备的scl连接到从设备的scl,主设备的sda
#       to slave sda. You must use external pull ups. Finally, both devices must share a ground.
#
# interface = rpc.rpc_i2c_master(slave_addr=0x12, rate=1000000)

# 取消注释以下行以设置您的OpenMV Cam通过SPI进行控制。
#
# * cs_pin - 从设备选择引脚。
# * freq - SPI总线时钟频率。
# * clk_polarity - 空闲时钟电平(0或1)。
# * clk_phase - 在时钟的第一个边沿(0)或第二个边沿(1)采样数据。
#
# 注意:主设备和从设备的设置必须匹配。将CS、SCLK、MOSI、MISO分别连接到CS、SCLK、MOSI、MISO。
#       Finally, both devices must share a common ground.
#
interface = rpc.rpc_spi_master(cs_pin="P3", freq=20000000, clk_polarity=1, clk_phase=0)

# 取消注释以下行以设置您的OpenMV Cam通过UART进行控制。
#
# * baudrate - 串行波特率。
#
# 注意:主从设备的波特率必须一致。将主设备的tx连接到从设备的rx,主设备的rx连接到
#       slave tx. Finally, both devices must share a common ground.
#
# interface = rpc.rpc_uart_master(baudrate=7500000)

##############################################################
# 回调处理程序
##############################################################


def get_frame_buffer_call_back(pixformat, framesize, cutthrough, silent):
    if not silent:
        print("Getting Remote Frame...")

    result = interface.call(
        "raw_image_snapshot", struct.pack("<II", pixformat, framesize)
    )
    if result is not None:
        w, h, pixformat, size = struct.unpack("<IIII", result)
        img = image.Image(
            w, h, pixformat, copy_to_fb=True
        )  # 分配已清除的帧缓冲区。

        if cutthrough:
            # 快速直通数据传输,无错误检查。

            # 在开始直通数据传输之前,我们需要同步主设备和
            # 从设备。返回时,两个设备已同步。
            result = interface.call("raw_image_read")
            if result is not None:
                # GET BYTES操作需立即执行,后续延迟极小。

                # 一次性读取所有图像数据(超大传输)。
                interface.get_bytes(img.bytearray(), 5000)  # 超时

        else:
            # 较慢的数据传输,带错误检查。

            # 以32/8 KB块为单位传输。
            chunk_size = (1 << 15) if omv.board_type() == "H7" else (1 << 13)

            if not silent:
                print("Reading %d bytes..." % size)
            for i in range(0, size, chunk_size):
                ok = False
                for j in range(3):  # 最多尝试3次。
                    result = interface.call(
                        "raw_image_read", struct.pack("<II", i, chunk_size)
                    )
                    if result is not None:
                        img.bytearray()[
                            i : i + chunk_size
                        ] = result  # 写入图像数据。
                        if not silent:
                            print("%.2f%%" % ((i * 100) / size))
                        ok = True
                        break
                    if not silent:
                        print("Retrying... %d/2" % (j + 1))
                if not ok:
                    if not silent:
                        print("Error!")
                    return None

        return img

    else:
        if not silent:
            print("Failed to get Remote Frame!")

    return None


clock = time.clock()
while True:
    clock.tick()

    # 您可以更改远程设备传输图像的像素格式和帧大小。
    # 通过修改以下参数。
    #
    # 当直通为假时,图像将通过RPC库传输,并对所有移动数据进行CRC校验和
    # 重试保护。为加快数据传输速度,可将直通设为真,以便
    # get_bytes()和put_bytes()在RPC调用完成后被调用,以传输数据
    # 更快地从一个图像缓冲区到另一个。注意:这之所以有效,是因为一旦RPC调用
    # 成功完成,主设备和从设备将完全同步。
    #
    img = get_frame_buffer_call_back(
        sensor.RGB565, sensor.QQVGA, cutthrough=True, silent=True
    )
    if img is not None:
        pass  # 您可以在此处处理图像。

    print(clock.fps())

results matching ""

    No results matching ""