例程讲解34-popular_features_as_the_remote_device OpenMV作为受控设备实现常见功能

# 远程控制-作为受控设备
#
# 该脚本将您的OpenMV Cam配置为协处理器,可以由另一个微控制器或计算机
#(例如Arduino,ESP8266 / ESP32,RaspberryPi,甚至另一个OpenMV Cam)远程控制。
# 这个脚本与 "popular_features_as_the_controller_device.py" 配对。

import image, network, math, rpc, sensor, struct, tf

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

# 上面的RPC库安装在您的OpenMV Cam上,并提供多种类,以允许您的OpenMV Cam控制CAN,I2C,SPI,UART或WIFI。

################################################################
# 选择你想要控制的OpenMV摄像头的接口。
################################################################

# 取消注释以下行以设置您的OpenMV Cam以控制CAN。
#
# * message_id - 用于CAN信息在can总线(11位)上进行数据传输。
# * bit_rate - CAN 比特率。
# * sampling_point - Tseg1/Tseg2 ratio. 一般为 75%. (50.0, 62.5, 75.0, 87.5, etc.)
#
# 注意:主从设备的message id和比特率必须匹配。将主设备的高电平引脚连接到从设备的高电平引脚,
# 将主设备的低电平引脚连接到从设备的低电平引脚。CAN总线必须接120欧姆的终端电阻。
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=250000, sampling_point=75)

# 取消注释以下行以设置您的OpenMV Cam以控制I2C。
#
# * slave_addr - I2C地址。
#
# 注意:主地址和从地址必须匹配。将主scl连接到从scl,将主sda连接到从sda。
# 您必须使用外部上拉电阻。最后,两个设备必须共地。
#
# 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。
# 最后,两个设备必须共地。
#
# interface = rpc.rpc_spi_slave(cs_pin="P3", clk_polarity=1, clk_phase=0)

# 取消注释以下行以设置您的OpenMV Cam以控制UART。
#
# * baudrate - 串行波特率。
#
# 注意:主和从波特率必须匹配。将主TX连接到从TX,将主TX连接到从TX。
# 最后,两个设备必须共地。
#
interface = rpc.rpc_uart_slave(baudrate=115200)

# Uncomment the below line to setup your OpenMV Cam for control over a USB VCP.
# 取消下面的注释来设置你的OpenMV Cam来控制USB VCP。
#
# interface = rpc.rpc_usb_vcp_slave()

# 取消下面的注释来设置你的OpenMV摄像头来控制WiFi。
#
# * ssid -要连接的WiFi网络。
# * ssid_key - WiFi网络密码。
# * ssid_security - WiFi安全性。
# * port - 用于将流量路由到的端口。
# * mode - 常规或接入点模式。
# * static_ip - 如果不是None,则为一个元组(IP地址,子网掩码,网关,DNS地址)
#
# interface = rpc.rpc_wifi_slave(ssid="",
#                                ssid_key="",
#                                ssid_security=network.WINC.WPA_PSK,
#                                port=0x1DBA,
#                                mode=network.WINC.MODE_STA,
#                                static_ip=None)

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

# 下面的回调使用的辅助方法。

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的最大整型数。

# 调用时返回视野中最大人脸的x,y,w和h。
#
# data没有用到
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() # 没有检测到
    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])

# 调用时,返回视图中是否存在“人”或“ no_person”。
#
# data未使用
def person_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    scores = tf.classify("person_detection", sensor.snapshot())[0].output()
    return ['unsure', 'person', 'no_person'][scores.index(max(scores))].encode()

# 调用时返回OpenMV Cam视野内最大qrcode的有效载荷字符串。
#
# data未使用
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() # 未检测到
    draw_detections(sensor.get_fb(), codes)
    return max(codes, key = lambda c: c.w() * c.h()).payload().encode()

# 当被调用时,返回一个json列表,其中包含视图中所有qrcode的json qrcode对象。
#
# data未使用
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() # 未检测到
    draw_detections(sensor.get_fb(), codes)
    return str(codes).encode()

# 调用时返回OpenMV Cam视场内最大的AprilTag的x/y重心,id号以及旋转角度。
#
# data未使用
def apriltag_detection(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QQVGA)
    tags = sensor.snapshot().find_apriltags()
    if not tags: return bytes() # 没有检测到
    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())))

# 调用时,返回一个json列表,其中包含视图中所有apriltag的json apriltag对象。
#
# data未使用
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() # 未检测到
    draw_detections(sensor.get_fb(), tags)
    return str(tags).encode()

# 调用时,返回OpenMV Cam视场内最大矩形码的有效负载字符串。
#
# data未使用
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() # 未检测到
    draw_detections(sensor.get_fb(), codes)
    return max(codes, key = lambda c: c.w() * c.h()).payload().encode()

# 调用时,返回一个json列表,其中包含了视图中所有datamatrices的json datamatrix对象。
#
# data未使用
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() # 未检测到
    draw_detections(sensor.get_fb(), codes)
    return str(codes).encode()

# 调用时返回OpenMV Cam视场中最大条形码的有效载荷字符串。
#
# data未使用
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() # 未检测到
    return max(codes, key = lambda c: c.w() * c.h()).payload().encode()

# 调用时,返回一个json列表,其中包含了视图中所有条形码的json条形码对象。
#
# data未使用
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() # 未检测到
    return str(codes).encode()

# 当被调用时,返回OpenMV Cam视场内最大色块的x/y重心。
#
# data是L_MIN、L_MAX、A_MIN、A_MAX、B_MIN、B_MAX的6字节颜色跟踪阈值元组。
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() # 未检测到
    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())

# 调用时,在一个RPC调用中从OpenMV Cam返回jpeg压缩图像。
# data未使用
def jpeg_snapshot(data):
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    return sensor.snapshot().compress(quality=90).bytearray()

# 添加回调。

interface.register_callback(face_detection)
interface.register_callback(person_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)

# 一旦所有的回调都被添加,我们就可以开始处理远程事件。
# loop()不返回。

interface.loop()

results matching ""

    No results matching ""