image_transfer_raw_as_the_remote_device.py
# Эта работа лицензирована по лицензии MIT.
# Copyright (c) 2013-2023 OpenMV LLC. All rights reserved.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Передача изображения — в роли удалённого устройства
#
# Этот скрипт предназначен для работы в паре с другой камерой OpenMV Cam, на которой выполняется "image_transfer_raw_as_the_controller_device.py"
#
# Этот скрипт показывает, как передать буфер кадра с одной камеры OpenMV Cam на другую.
import rpc
import csi
import struct
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi0.snapshot(time=2000)
# Указанная выше библиотека 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 и т. д.)
#
# ПРИМЕЧАНИЕ: идентификаторы сообщений и скорости CAN у ведущего и ведомого устройств должны совпадать. Соедините CAN high ведущего с
# CAN high ведомого, а CAN low ведущего — с CAN low ведомого. Шина CAN должна быть терминирована резисторами 120 Ом.
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=1000000, sample_point=75.0)
# Раскомментируйте следующую строку, чтобы настроить камеру OpenMV Cam для управления по I2C.
#
# * slave_addr — адрес I2C.
#
# ПРИМЕЧАНИЕ: адреса ведущего и ведомого устройств должны совпадать. Соедините scl ведущего со scl ведомого, а sda ведущего
# со sda ведомого. Необходимо использовать внешние подтягивающие резисторы. Наконец, оба устройства должны иметь общую землю.
#
# interface = rpc.rpc_i2c_slave(slave_addr=0x12)
# Раскомментируйте следующую строку, чтобы настроить камеру OpenMV Cam для управления по SPI.
#
# * cs_pin — вывод выбора ведомого устройства (Slave Select).
# * clk_polarity — уровень тактового сигнала в состоянии простоя (0 или 1).
# * clk_phase — выборка данных по первому (0) или второму (1) фронту тактового сигнала.
#
# ПРИМЕЧАНИЕ: настройки ведущего и ведомого устройств должны совпадать. Соедините CS, SCLK, MOSI, MISO с CS, SCLK, MOSI, MISO соответственно.
# Наконец, оба устройства должны иметь общую землю.
#
interface = rpc.rpc_spi_slave(cs_pin="P3", clk_polarity=1, clk_phase=0)
# Раскомментируйте следующую строку, чтобы настроить камеру OpenMV Cam для управления по UART.
#
# * baudrate — скорость передачи последовательного порта.
#
# ПРИМЕЧАНИЕ: скорости передачи ведущего и ведомого устройств должны совпадать. Соедините tx ведущего с rx ведомого, а rx ведущего —
# с tx ведомого. Наконец, оба устройства должны иметь общую землю.
#
# interface = rpc.rpc_uart_slave(baudrate=7500000)
################################################################
# Обратные вызовы
################################################################
img = None
img_ba = None
img_mv = None
# При вызове устанавливает pixformat и framesize, делает снимок
# и возвращает форму (shape) буфера кадра для сохранения изображения.
#
# данные — это 4 байта pixformat и 4 байта framesize.
def raw_image_snapshot(data):
global img, img_ba, img_mv
pixformat, framesize = struct.unpack("<II", data)
csi0.pixformat(pixformat)
csi0.framesize(framesize)
img = csi0.snapshot()
img_ba = img.bytearray()
img_mv = memoryview(img_ba)
return struct.pack(
"<IIII", csi0.width(), csi0.height(), csi0.pixformat(), img.size()
)
def raw_image_read_cb():
interface.put_bytes(img_ba, 5000) # тайм-аут
# Прочитать данные из буфера кадра по заданному смещению и размеру.
# Если данные пусты, передача планируется после завершения вызова RPC.
#
# данные — это 4 байта размера и 4 байта смещения.
def raw_image_read(data):
if not len(data):
interface.schedule_callback(raw_image_read_cb)
return bytes()
else:
offset, size = struct.unpack("<II", data)
return img_mv[offset:offset + size]
# Зарегистрировать обратные вызовы.
interface.register_callback(raw_image_snapshot)
interface.register_callback(raw_image_read)
# После регистрации всех обратных вызовов можно начинать
# обработку удалённых событий. interface.loop() не возвращает управление.
interface.loop()