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

# 本作品采用MIT许可证授权。
# 版权所有 (c) 2013-2023 OpenMV LLC。保留所有权利。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# 远程控制 - 作为远程设备
#
# 此脚本将您的OpenMV摄像头配置为可被远程控制的协处理器,
# 控制设备可以是Arduino、ESP8266/ESP32、RaspberryPi等微控制器或计算机,
# 甚至另一台OpenMV摄像头。
#
# 此脚本设计用于与“popular_features_as_the_controller_device.py”配对使用,

import image
import math
import rpc
import sensor
import struct

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)

# 上述RPC库已安装在您的OpenMV Cam上,并提供了多个类,
# 使您的OpenMV摄像头能够通过CAN、I2C、SPI、UART、USB VCP或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、87.5等)
#
# 注意:主设备和从设备的消息ID和CAN比特率必须匹配。将主设备的CAN高连接到从设备。
#       can high and master can low to slave can lo. The can bus must be terminated with 120 ohms.
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=250000, sample_point=75)

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

# 取消注释以下行以设置您的OpenMV Cam通过SPI进行控制。
#
# * cs_pin - 从设备选择引脚。
# * 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_slave(cs_pin="P3", 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_slave(baudrate=115200)

# 取消注释以下行以设置您的OpenMV Cam通过USB VCP进行控制。
#
# interface = rpc.rpc_usb_vcp_slave()

# 取消注释以下行以设置您的OpenMV Cam通过局域网进行控制。
#
# 导入网络
# network_if = network.LAN()
# network_if.active(True)
# network_if.ifconfig('dhcp')
#
# interface = rpc.rpc_network_slave(network_if)

# 取消注释以下行以设置您的OpenMV Cam通过无线局域网进行控制。
#
# 导入网络
# network_if = network.WLAN(network.STA_IF)
# network_if.active(True)
# network_if.connect('您的SSID', '您的密码')
#
# interface = rpc.rpc_network_slave(network_if)

################################################################
# 回调
################################################################

# 以下回调函数使用的辅助方法。


def draw_detections(img, dects):
    for d in dects:
        c = d.corners()
        l = len(c)
        for i in range(l):
            img.draw_line(c[(i + 0) % l] + c[(i + 1) % l], color=(0, 255, 0))
        img.draw_rectangle(d.rect(), color=(255, 0, 0))


# 远程控制通过回调方法实现,控制器设备
# 通过本设备的rpc模块调用这些方法。回调
# 是接收bytes()对象作为参数并返回
# bytes()对象作为结果的函数。rpc模块
# 负责在链路上传输这些bytes()对象。
# bytes()可能是micropython int的最大大小。


# 调用时返回视野中最大人脸的x、y、w和h。
#
# data is unused
def face_detection(data):
    sensor.set_pixformat(sensor.GRAYSCALE)
    sensor.set_framesize(sensor.QVGA)
    faces = (
        sensor.snapshot()
        .gamma_corr(contrast=1.5)
        .find_features(image.HaarCascade("frontalface"))
    )
    if not faces:
        return bytes()  # No detections.
    for f in faces:
        sensor.get_fb().draw_rectangle(f, color=(255, 255, 255))
    out_face = max(faces, key=lambda f: f[2] * f[3])
    return struct.pack("<HHHH", out_face[0], out_face[1], out_face[2], out_face[3])


# When called returns the payload string for the largest qrcode
# within the OpenMV Cam's field-of-view.
#
# data is unused
def qrcode_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.VGA)
    sensor.set_windowing((320, 240))
    codes = sensor.snapshot().find_qrcodes()
    if not codes:
        return bytes()  # No detections.
    draw_detections(sensor.get_fb(), codes)
    return max(codes, key=lambda c: c.w() * c.h()).payload().encode()


# When called returns a json list of json qrcode objects for all qrcodes in view.
#
# data is unused
def all_qrcode_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.VGA)
    sensor.set_windowing((320, 240))
    codes = sensor.snapshot().find_qrcodes()
    if not codes:
        return bytes()  # No detections.
    draw_detections(sensor.get_fb(), codes)
    return str(codes).encode()


# When called returns the x/y centroid, id number, and rotation of the largest
# AprilTag within the OpenMV Cam's field-of-view.
#
# data is unused
def apriltag_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QQVGA)
    tags = sensor.snapshot().find_apriltags()
    if not tags:
        return bytes()  # No detections.
    draw_detections(sensor.get_fb(), tags)
    output_tag = max(tags, key=lambda t: t.w * t.h)
    return struct.pack(
        "<HHHH",
        output_tag.cx,
        output_tag.cy,
        output_tag.id,
        int(math.degrees(output_tag.rotation)),
    )


# When called returns a json list of json apriltag objects for all apriltags in view.
#
# data is unused
def all_apriltag_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QQVGA)
    tags = sensor.snapshot().find_apriltags()
    if not tags:
        return bytes()  # No detections.
    draw_detections(sensor.get_fb(), tags)
    return str(tags).encode()


# When called returns the payload string for the largest datamatrix
# within the OpenMV Cam's field-of-view.
#
# data is unused
def datamatrix_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.VGA)
    sensor.set_windowing((320, 240))
    codes = sensor.snapshot().find_datamatrices()
    if not codes:
        return bytes()  # No detections.
    draw_detections(sensor.get_fb(), codes)
    return max(codes, key=lambda c: c.w() * c.h()).payload().encode()


# When called returns a json list of json datamatrix objects for all datamatrices in view.
#
# data is unused
def all_datamatrix_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.VGA)
    sensor.set_windowing((320, 240))
    codes = sensor.snapshot().find_datamatrices()
    if not codes:
        return bytes()  # No detections.
    draw_detections(sensor.get_fb(), codes)
    return str(codes).encode()


# When called returns the payload string for the largest barcode
# within the OpenMV Cam's field-of-view.
#
# data is unused
def barcode_detection(data):
    sensor.set_pixformat(sensor.GRAYSCALE)
    sensor.set_framesize(sensor.VGA)
    sensor.set_windowing((sensor.width(), sensor.height() // 8))
    codes = sensor.snapshot().find_barcodes()
    if not codes:
        return bytes()  # No detections.
    return max(codes, key=lambda c: c.w() * c.h()).payload().encode()


# 调用时返回视野中所有条形码的json条形码对象的json列表。
#
# data is unused
def all_barcode_detection(data):
    sensor.set_pixformat(sensor.GRAYSCALE)
    sensor.set_framesize(sensor.VGA)
    sensor.set_windowing((sensor.width(), sensor.height() // 8))
    codes = sensor.snapshot().find_barcodes()
    if not codes:
        return bytes()  # No detections.
    return str(codes).encode()


# When called returns the x/y centroid of the largest blob
# within the OpenMV Cam's field-of-view.
#
# data is the 6-byte color tracking threshold tuple of L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX.
def color_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    thresholds = struct.unpack("<bbbbbb", data)
    blobs = sensor.snapshot().find_blobs(
        [thresholds], pixels_threshold=500, area_threshold=500, merge=True, margin=20
    )
    if not blobs:
        return bytes()  # No detections.
    for b in blobs:
        sensor.get_fb().draw_rectangle(b.rect(), color=(255, 0, 0))
        sensor.get_fb().draw_cross(b.cx(), b.cy(), color=(0, 255, 0))
    out_blob = max(blobs, key=lambda b: b.density())
    return struct.pack("<HH", out_blob.cx(), out_blob.cy())


# When called returns a jpeg compressed image from the OpenMV
# Cam in one RPC call.
#
# data is unused
def jpeg_snapshot(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    img = sensor.snapshot()
    img.to_jpeg(quality=90)
    return img.bytearray()


# 注册回调。

interface.register_callback(face_detection)
interface.register_callback(qrcode_detection)
interface.register_callback(all_qrcode_detection)
interface.register_callback(apriltag_detection)
interface.register_callback(all_apriltag_detection)
interface.register_callback(datamatrix_detection)
interface.register_callback(all_datamatrix_detection)
interface.register_callback(barcode_detection)
interface.register_callback(all_barcode_detection)
interface.register_callback(color_detection)
interface.register_callback(jpeg_snapshot)

# 一旦所有回调都已注册,我们就可以开始
# 处理远程事件。interface.loop()不会返回。

interface.loop()

results matching ""

    No results matching ""