popular_features_as_the_remote_device.py

# この作品はMITライセンスの下で提供されています。
# Copyright (c) 2013-2023 OpenMV LLC. 全著作権所有。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# リモートコントロール - リモートデバイスとして
#
# このスクリプトは、OpenMV Camを以下からリモート制御可能なコプロセッサとして設定します
# Arduino、ESP8266/ESP32、RaspberryPiなどの別のマイクロコントローラやコンピュータ、
# あるいは別のOpenMV Camからも。
#
# このスクリプトは"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)

# 上記のRPCライブラリはOpenMV Camにインストールされており、以下のための複数のクラスを提供します
# OpenMV CamをCAN、I2C、SPI、またはUART経由で制御できるようにします。

################################################################
# 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 Highをスレーブの
# CAN Highに、マスターのCAN Lowをスレーブのcan loに接続してください。CANバスは120オームで終端する必要があります。
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=250000, sample_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)または2番目のエッジ(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をスレーブのrxに、マスターのrxを
# スレーブのtxに接続してください。最後に、両方のデバイスは共通のグラウンドを共有する必要があります。
#
interface = rpc.rpc_uart_slave(baudrate=115200)

################################################################
# コールバック
################################################################

# 以下のコールバックで使用されるヘルパーメソッド。


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))


# リモートコントロールは、コントローラーが
# このデバイス上のrpcモジュールを介して呼び出すコールバックメソッドによって動作します。コールバックは
# bytes()オブジェクトを引数として受け取り、
# bytes()オブジェクトを結果として返す関数です。rpcモジュールは
# リンクを介したbytes()オブジェクトの転送を処理します。
# bytes()のサイズはmicropythonのint最大値まで可能です。


# 呼び出されると、視野内で最大の顔のx、y、w、hを返します。
#
# dataは使用されません
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()  # 検出なし。
    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])


# 呼び出されると、最大のQRコードのペイロード文字列を返します
# OpenMV Camの視野内で。
#
# dataは使用されません
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()  # 検出なし。
    draw_detections(img, codes)
    return max(codes, key=lambda c: c.w * c.h).payload.encode()


# 呼び出されると、視野内のすべてのQRコードに対するjson qrcodeオブジェクトのjsonリストを返します。
#
# dataは使用されません
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()  # 検出なし。
    draw_detections(img, codes)
    return str(codes).encode()


# 呼び出されると、最大の
# OpenMV Camの視野内にあるAprilTagのx/y重心、ID番号、回転角を返します。
#
# dataは使用されません
def apriltag_detection(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.QQVGA)
    img = csi0.snapshot()
    tags = img.find_apriltags()
    if not tags:
        return bytes()  # 検出なし。
    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)),
    )


# 呼び出されると、視野内のすべてのAprilTagに対するjson apriltagオブジェクトのjsonリストを返します。
#
# dataは使用されません
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()  # 検出なし。
    draw_detections(img, tags)
    return str(tags).encode()


# 呼び出されると、最大のデータマトリクスのペイロード文字列を返します
# OpenMV Camの視野内で。
#
# dataは使用されません
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()  # 検出なし。
    draw_detections(img, codes)
    return max(codes, key=lambda c: c.w * c.h).payload.encode()


# 呼び出されると、視野内のすべてのデータマトリクスに対するjson datamatrixオブジェクトのjsonリストを返します。
#
# dataは使用されません
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()  # 検出なし。
    draw_detections(img, codes)
    return str(codes).encode()


# 呼び出されると、最大のバーコードのペイロード文字列を返します
# OpenMV Camの視野内で。
#
# dataは使用されません
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()  # 検出なし。
    return max(codes, key=lambda c: c.w * c.h).payload.encode()


# 呼び出されると、視野内のすべてのバーコードに対するjson barcodeオブジェクトのjsonリストを返します。
#
# dataは使用されません
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()  # 検出なし。
    return str(codes).encode()


# 呼び出されると、最大のブロブのx/y重心を返します
# OpenMV Camの視野内で。
#
# dataはL_MIN、L_MAX、A_MIN、A_MAX、B_MIN、B_MAXからなる6バイトのカラートラッキング閾値タプルです。
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()  # 検出なし。
    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)


# 呼び出されると、OpenMV
# Camから1回のRPC呼び出しでJPEG圧縮画像を返します。
#
# dataは使用されません
def jpeg_snapshot(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.QVGA)
    img = csi0.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 ""