popular_features_as_the_remote_device.py

# Este trabalho está licenciado sob a licença MIT.
# Copyright (c) 2013-2023 OpenMV LLC. Todos os direitos reservados.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Controle remoto - Como o dispositivo remoto
#
# Este script configura a sua OpenMV Cam como um coprocessador que pode ser controlado remotamente por
# outro microcontrolador ou computador, como um Arduino, ESP8266/ESP32, RaspberryPi, e
# até mesmo outra OpenMV Cam.
#
# Este script foi projetado para ser combinado com "popular_features_as_the_controller_device.py".

import image
import math
import rpc
import csi
import struct

csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi0.snapshot(time=2000)

# A biblioteca RPC acima está instalada na sua OpenMV Cam e fornece diversas classes para
# permitir que sua OpenMV Cam seja controlada via CAN, I2C, SPI ou UART.

################################################################
# Escolha a interface pela qual deseja controlar a sua OpenMV Cam.
################################################################

# Descomente a linha abaixo para configurar sua OpenMV Cam para controle via CAN.
#
# * message_id - Mensagem CAN usada para transporte de dados no barramento CAN (11 bits).
# * bit_rate - Taxa de bits do CAN.
# * sample_point - Proporção Tseg1/Tseg2. Tipicamente 75%. (50.0, 62.5, 75, 87.5, etc.)
#
# NOTA: Os message ids e as taxas de bits do CAN do mestre e do escravo devem coincidir. Conecte o can high do mestre ao
# can high do escravo e o can low do mestre ao can low do escravo. O barramento CAN deve ser terminado com 120 ohms.
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=250000, sample_point=75)

# Descomente a linha abaixo para configurar sua OpenMV Cam para controle via I2C.
#
# * slave_addr - Endereço I2C.
#
# NOTA: Os endereços do mestre e do escravo devem coincidir. Conecte o scl do mestre ao scl do escravo e o sda do mestre
# ao sda do escravo. É necessário usar pull-ups externos. Por fim, ambos os dispositivos devem compartilhar um ground.
#
# interface = rpc.rpc_i2c_slave(slave_addr=0x12)

# Descomente a linha abaixo para configurar sua OpenMV Cam para controle via SPI.
#
# * cs_pin - Pino de seleção do escravo (Slave Select).
# * clk_polarity - Nível do clock em repouso (0 ou 1).
# * clk_phase - Amostra dados na primeira (0) ou segunda borda (1) do clock.
#
# NOTA: As configurações do mestre e do escravo devem coincidir. Conecte CS, SCLK, MOSI, MISO a CS, SCLK, MOSI, MISO.
# Por fim, ambos os dispositivos devem compartilhar um ground comum.
#
# interface = rpc.rpc_spi_slave(cs_pin="P3", clk_polarity=1, clk_phase=0)

# Descomente a linha abaixo para configurar sua OpenMV Cam para controle via UART.
#
# * baudrate - Taxa de transmissão serial.
#
# NOTA: As taxas de baud do mestre e do escravo devem coincidir. Conecte o tx do mestre ao rx do escravo e o rx do mestre ao
# tx do escravo. Por fim, ambos os dispositivos devem compartilhar um ground comum.
#
interface = rpc.rpc_uart_slave(baudrate=115200)

################################################################
# Call Backs
################################################################

# Métodos auxiliares usados pelos call backs abaixo.


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


# O controle remoto funciona por meio de métodos de call back que o dispositivo
# controlador chama via o módulo rpc neste dispositivo. Call backs
# são funções que recebem um objeto bytes() como argumento
# e retornam um objeto bytes() como resultado. O módulo rpc
# se encarrega de mover os objetos bytes() através do link.
# bytes() pode ter o tamanho máximo de int do micropython.


# Quando chamado, retorna x, y, w e h do maior rosto dentro do campo de visão.
#
# data não é usado
def face_detection(data):
    csi0.pixformat(csi.GRAYSCALE)
    csi0.framesize(csi.QVGA)
    img = csi0.snapshot()
    faces = (
        img.gamma_corr(contrast=1.5)
        .find_features(image.HaarCascade("/rom/haarcascade_frontalface.cascade"))
    )
    if not faces:
        return bytes()  # Nenhuma detecção.
    for f in faces:
        img.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])


# Quando chamado, retorna a string de payload do maior qrcode
# dentro do campo de visão da OpenMV Cam.
#
# data não é usado
def qrcode_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.VGA)
    csi0.window((320, 240))
    img = csi0.snapshot()
    codes = img.find_qrcodes()
    if not codes:
        return bytes()  # Nenhuma detecção.
    draw_detections(img, codes)
    return max(codes, key=lambda c: c.w * c.h).payload.encode()


# Quando chamado, retorna uma lista json de objetos json de qrcode para todos os qrcodes visíveis.
#
# data não é usado
def all_qrcode_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.VGA)
    csi0.window((320, 240))
    img = csi0.snapshot()
    codes = img.find_qrcodes()
    if not codes:
        return bytes()  # Nenhuma detecção.
    draw_detections(img, codes)
    return str(codes).encode()


# Quando chamado, retorna o centroide x/y, o número de id e a rotação do maior
# AprilTag dentro do campo de visão da OpenMV Cam.
#
# data não é usado
def apriltag_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.QQVGA)
    img = csi0.snapshot()
    tags = img.find_apriltags()
    if not tags:
        return bytes()  # Nenhuma detecção.
    draw_detections(img, 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)),
    )


# Quando chamado, retorna uma lista json de objetos json de apriltag para todos os apriltags visíveis.
#
# data não é usado
def all_apriltag_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.QQVGA)
    img = csi0.snapshot()
    tags = img.find_apriltags()
    if not tags:
        return bytes()  # Nenhuma detecção.
    draw_detections(img, tags)
    return str(tags).encode()


# Quando chamado, retorna a string de payload do maior datamatrix
# dentro do campo de visão da OpenMV Cam.
#
# data não é usado
def datamatrix_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.VGA)
    csi0.window((320, 240))
    img = csi0.snapshot()
    codes = img.find_datamatrices()
    if not codes:
        return bytes()  # Nenhuma detecção.
    draw_detections(img, codes)
    return max(codes, key=lambda c: c.w * c.h).payload.encode()


# Quando chamado, retorna uma lista json de objetos json de datamatrix para todos os datamatrices visíveis.
#
# data não é usado
def all_datamatrix_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.VGA)
    csi0.window((320, 240))
    img = csi0.snapshot()
    codes = img.find_datamatrices()
    if not codes:
        return bytes()  # Nenhuma detecção.
    draw_detections(img, codes)
    return str(codes).encode()


# Quando chamado, retorna a string de payload do maior código de barras
# dentro do campo de visão da OpenMV Cam.
#
# data não é usado
def barcode_detection(data):
    csi0.pixformat(csi.GRAYSCALE)
    csi0.framesize(csi.VGA)
    csi0.window((csi0.width(), csi0.height() // 8))
    img = csi0.snapshot()
    codes = img.find_barcodes()
    if not codes:
        return bytes()  # Nenhuma detecção.
    return max(codes, key=lambda c: c.w * c.h).payload.encode()


# Quando chamado, retorna uma lista json de objetos json de código de barras para todos os códigos de barras visíveis.
#
# data não é usado
def all_barcode_detection(data):
    csi0.pixformat(csi.GRAYSCALE)
    csi0.framesize(csi.VGA)
    csi0.window((csi0.width(), csi0.height() // 8))
    img = csi0.snapshot()
    codes = img.find_barcodes()
    if not codes:
        return bytes()  # Nenhuma detecção.
    return str(codes).encode()


# Quando chamado, retorna o centroide x/y do maior blob
# dentro do campo de visão da OpenMV Cam.
#
# data é a tupla de 6 bytes do limiar de rastreamento de cor: L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX.
def color_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.QVGA)
    thresholds = struct.unpack("<bbbbbb", data)
    img = csi0.snapshot()
    blobs = img.find_blobs(
        [thresholds], pixels_threshold=500, area_threshold=500, merge=True, margin=20
    )
    if not blobs:
        return bytes()  # Nenhuma detecção.
    for b in blobs:
        img.draw_detection(b, color1=(255, 0, 0), color2=(0, 255, 0))
    out_blob = max(blobs, key=lambda b: b.density)
    return struct.pack("<HH", out_blob.cx, out_blob.cy)


# Quando chamado, retorna uma imagem comprimida em jpeg da OpenMV
# Cam em uma única chamada RPC.
#
# data não é usado
def jpeg_snapshot(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.QVGA)
    img = csi0.snapshot()
    img.to_jpeg(quality=90)
    return img.bytearray()


# Registrar call backs.

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)

# Depois que todos os call backs forem registrados, podemos iniciar
# o processamento de eventos remotos. interface.loop() não retorna.

interface.loop()

results matching ""

    No results matching ""