image_transfer_raw_as_the_controller_device.py

# Esta obra está licenciada bajo la licencia MIT.
# Copyright (c) 2013-2023 OpenMV LLC. Todos los derechos reservados.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Transferencia de imagen - Como dispositivo controlador
#
# Este script está diseñado para emparejarse con otra OpenMV Cam que ejecute "image_transfer_raw_as_the_remote_device.py"
#
# Este script muestra cómo transferir el framebuffer de una OpenMV Cam a otra.

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

# La biblioteca RPC mencionada arriba está instalada en su OpenMV Cam y proporciona varias clases para
# permitiendo que su OpenMV Cam controle mediante CAN, I2C, SPI, UART o LAN/WLAN.

##############################################################
# Elija la interfaz mediante la cual desea controlar una OpenMV Cam.
##############################################################

# Descomente la siguiente línea para configurar su OpenMV Cam para controlar mediante CAN.
#
# * message_id: mensaje CAN que se usará para el transporte de datos en el bus CAN (11 bits).
# * bit_rate: velocidad de bits del CAN.
# * sample_point - Relación Tseg1/Tseg2. Típicamente 75%. (50.0, 62.5, 75.0, 87.5, etc.)
#
# NOTA: los IDs de mensaje y las velocidades de bits CAN del maestro y del esclavo deben coincidir. Conecte el can high del maestro al
# can high del esclavo, y el can low del maestro al can low del esclavo. El bus CAN debe terminarse con 120 ohmios.
#
# interface = rpc.rpc_can_master(message_id=0x7FF, bit_rate=1000000, sample_point=75.0)

# Descomente la siguiente línea para configurar su OpenMV Cam para controlar mediante I2C.
#
# * slave_addr: dirección I2C.
# * rate - Frecuencia de reloj del bus I2C.
#
# NOTA: las direcciones del maestro y del esclavo deben coincidir. Conecte el scl del maestro al scl del esclavo y el sda del maestro
# al sda del esclavo. Debe usar resistencias pull-up externas. Finalmente, ambos dispositivos deben compartir una tierra común.
#
# interface = rpc.rpc_i2c_master(slave_addr=0x12, rate=1000000)

# Descomente la siguiente línea para configurar su OpenMV Cam para controlar mediante SPI.
#
# * cs_pin: pin de selección de esclavo (Slave Select).
# * freq - Frecuencia de reloj del bus SPI
# * clk_polarity: nivel del reloj en reposo (0 o 1).
# * clk_phase: muestrear los datos en el primer (0) o segundo flanco (1) del reloj.
#
# NOTA: la configuración del maestro y del esclavo debe coincidir. Conecte CS, SCLK, MOSI, MISO a CS, SCLK, MOSI, MISO.
# Finalmente, ambos dispositivos deben compartir una tierra común.
#
interface = rpc.rpc_spi_master(cs_pin="P3", freq=20000000, clk_polarity=1, clk_phase=0)

# Descomente la siguiente línea para configurar su OpenMV Cam para controlar mediante UART.
#
# * baudrate: velocidad en baudios del puerto serie.
#
# NOTA: las velocidades en baudios del maestro y del esclavo deben coincidir. Conecte el tx del maestro al rx del esclavo y el rx del maestro
# al tx del esclavo. Finalmente, ambos dispositivos deben compartir una tierra común.
#
# interface = rpc.rpc_uart_master(baudrate=7500000)

##############################################################
# Manejadores de funciones callback
##############################################################


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)  # Reservar un framebuffer inicializado en cero.
        img_ba = img.bytearray()

        if cutthrough:
            # Transferencia de datos rápida (cutthrough) sin comprobación de errores.

            # Antes de iniciar la transferencia de datos cutthrough, necesitamos sincronizar tanto el dispositivo maestro como el
            # dispositivo esclavo. Al retornar, ambos dispositivos están sincronizados.
            result = interface.call("raw_image_read")
            if result is not None:
                # GET BYTES DEBE EJECUTARSE A CONTINUACIÓN INMEDIATAMENTE CON POCO RETRASO.

                # Lee todos los datos de la imagen en una única transferencia muy grande.
                interface.get_bytes(img_ba, 5000)  # timeout

        else:
            # Transferencia de datos más lenta con comprobación de errores.

            # Transfiere fragmentos 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):  # Intenta hasta 3 veces.
                    result = interface.call(
                        "raw_image_read", struct.pack("<II", i, chunk_size)
                    )
                    if result is not None:
                        img_ba[i:i + chunk_size] = result  # Escribe los datos de la imagen.
                        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()

    # Puede cambiar el pixformat y el framesize de la imagen transferida desde el dispositivo remoto
    # modificando los siguientes argumentos.
    #
    # Cuando cutthrough es False, la imagen se transferirá a través de la librería RPC con CRC y
    # protección de reintento en todos los datos movidos. Para una transferencia de datos más rápida, establezca cutthrough en True para que
    # get_bytes() y put_bytes() se llamen después de que se complete una llamada RPC para transferir datos
    # más rápidamente de un buffer de imagen a otro. Nota: Esto funciona porque una vez que una llamada RPC
    # se completa con éxito, tanto el dispositivo maestro como el esclavo quedan completamente sincronizados.
    #
    img = get_frame_buffer_call_back(
        csi.RGB565, csi.QQVGA, cutthrough=True, silent=True
    )
    if img is not None:
        pass  # Puede procesar la imagen aquí.

    print(clock.fps())

results matching ""

    No results matching ""