image_transfer_raw_as_the_controller_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
#
# Transferência de imagem - Como o dispositivo controlador
#
# Este script foi feito para ser combinado com outra OpenMV Cam rodando "image_transfer_raw_as_the_remote_device.py"
#
# Este script mostra como transferir o frame buffer de uma OpenMV Cam para outra.

import image
import omv
import rpc
import csi
import struct
import time

# A biblioteca RPC acima está instalada na sua OpenMV Cam e fornece diversas classes para
# permitindo que sua OpenMV Cam controle via CAN, I2C, SPI, UART ou LAN/WLAN.

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

# Descomente a linha abaixo para configurar sua OpenMV Cam para controlar 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.0, 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_master(message_id=0x7FF, bit_rate=1000000, sample_point=75.0)

# Descomente a linha abaixo para configurar sua OpenMV Cam para controlar via I2C.
#
# * slave_addr - Endereço I2C.
# * rate - Frequência do clock do barramento 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_master(slave_addr=0x12, rate=1000000)

# Descomente a linha abaixo para configurar sua OpenMV Cam para controlar via SPI.
#
# * cs_pin - Pino de seleção do escravo (Slave Select).
# * freq - Frequência do clock do barramento SPI
# * 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_master(cs_pin="P3", freq=20000000, clk_polarity=1, clk_phase=0)

# Descomente a linha abaixo para configurar sua OpenMV Cam para controlar 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_master(baudrate=7500000)

##############################################################
# Manipuladores de Call Back
##############################################################


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)  # Alocar frame buffer zerado.
        img_ba = img.bytearray()

        if cutthrough:
            # Transferência de dados rápida (cutthrough) sem verificação de erros.

            # Antes de iniciar a transferência de dados cutthrough, precisamos sincronizar tanto o mestre quanto o
            # dispositivo escravo. No retorno, ambos os dispositivos estão sincronizados.
            result = interface.call("raw_image_read")
            if result is not None:
                # GET BYTES PRECISA SER EXECUTADO IMEDIATAMENTE A SEGUIR, COM POUCO ATRASO.

                # Ler todos os dados da imagem em uma única transferência bem grande.
                interface.get_bytes(img_ba, 5000)  # timeout

        else:
            # Transferência de dados mais lenta com verificação de erros.

            # Transferir blocos de 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):  # Tentar até 3 vezes.
                    result = interface.call(
                        "raw_image_read", struct.pack("<II", i, chunk_size)
                    )
                    if result is not None:
                        img_ba[i:i + chunk_size] = result  # Escrever os dados da imagem.
                        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()

    # Você pode alterar o pixformat e o framesize da imagem transferida do dispositivo remoto
    # modificando os argumentos abaixo.
    #
    # Quando cutthrough é False, a imagem será transferida pela biblioteca RPC com proteção de CRC e
    # retransmissão em todos os dados movidos. Para uma transferência de dados mais rápida, defina cutthrough como True para que
    # get_bytes() e put_bytes() sejam chamados após a conclusão de uma chamada RPC para transferir dados
    # mais rapidamente de um buffer de imagem para outro. Nota: Isso funciona porque, assim que uma chamada RPC
    # é concluída com sucesso, tanto o dispositivo mestre quanto o escravo ficam completamente sincronizados.
    #
    img = get_frame_buffer_call_back(
        csi.RGB565, csi.QQVGA, cutthrough=True, silent=True
    )
    if img is not None:
        pass  # Você pode processar a imagem aqui.

    print(clock.fps())

results matching ""

    No results matching ""