popular_features_as_the_remote_device.py

# هذا العمل مرخص بموجب ترخيص MIT.
# حقوق النشر (c) 2013-2023 OpenMV LLC. جميع الحقوق محفوظة.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# التحكم عن بعد - كجهاز بعيد
#
# يقوم هذا السكربت بتهيئة كاميرا OpenMV كمعالج مساعد يمكن التحكم به عن بعد من قبل
# متحكم دقيق أو حاسوب آخر مثل Arduino أو ESP8266/ESP32 أو RaspberryPi، و
# حتى كاميرا OpenMV أخرى.
#
# صُمم هذا السكربت ليعمل مع "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 الخاصة بك وتوفر عدة أصناف من أجل
# السماح بالتحكم في كاميرا OpenMV عبر CAN أو I2C أو SPI أو UART.

################################################################
# اختر الواجهة التي ترغب في التحكم بكاميرا OpenMV من خلالها.
################################################################

# قم بإلغاء التعليق عن السطر أدناه لإعداد كاميرا OpenMV للتحكم بها عبر CAN.
#
# * message_id - رسالة CAN المستخدمة لنقل البيانات على ناقل CAN (11-بت).
# * bit_rate - معدل بتات CAN.
# * sample_point - نسبة Tseg1/Tseg2. عادةً 75%. (50.0، 62.5، 75، 87.5، إلخ)
#
# ملاحظة: يجب أن تتطابق معرّفات الرسائل ومعدلات بتات CAN بين الجهاز الرئيسي والتابع. قم بتوصيل can high للجهاز الرئيسي بـ
# can high للجهاز التابع وcan low للجهاز الرئيسي بـ can low للجهاز التابع. يجب إنهاء ناقل can بمقاومة 120 أوم.
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=250000, sample_point=75)

# قم بإلغاء التعليق عن السطر أدناه لإعداد كاميرا OpenMV للتحكم بها عبر I2C.
#
# * slave_addr - عنوان I2C.
#
# ملاحظة: يجب أن تتطابق عناوين الجهاز الرئيسي والتابع. قم بتوصيل scl للجهاز الرئيسي بـ scl للجهاز التابع وsda للجهاز الرئيسي
# بـ sda للجهاز التابع. يجب استخدام مقاومات سحب (pull ups) خارجية. وأخيرًا، يجب أن يشترك الجهازان في نفس الأرضي (ground).
#
# interface = rpc.rpc_i2c_slave(slave_addr=0x12)

# قم بإلغاء التعليق عن السطر أدناه لإعداد كاميرا OpenMV للتحكم بها عبر SPI.
#
# * cs_pin - دبوس اختيار الجهاز التابع (Slave Select).
# * 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 للتحكم بها عبر UART.
#
# * baudrate - معدل البود التسلسلي (Serial Baudrate).
#
# ملاحظة: يجب أن تتطابق معدلات البود بين الجهاز الرئيسي والتابع. قم بتوصيل tx للجهاز الرئيسي بـ rx للجهاز التابع وrx للجهاز الرئيسي بـ
# tx للجهاز التابع. وأخيرًا، يجب أن يشترك الجهازان في أرضي مشترك.
#
interface = rpc.rpc_uart_slave(baudrate=115200)

################################################################
# دوال رد النداء (Call Backs)
################################################################

# طرق مساعدة تستخدمها دوال رد النداء أدناه.


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 الصحيح.


# عند استدعائها، تُرجع x وy وw وh لأكبر وجه ضمن مجال الرؤية.
#
# البيانات غير مستخدمة
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])


# عند استدعائها، تُرجع سلسلة المحتوى (payload) لأكبر رمز استجابة سريعة (qrcode)
# ضمن مجال رؤية كاميرا OpenMV.
#
# البيانات غير مستخدمة
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()


# عند استدعائها، تُرجع قائمة json من كائنات qrcode بصيغة json لجميع رموز الاستجابة السريعة ضمن مجال الرؤية.
#
# البيانات غير مستخدمة
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()


# عند استدعائها، تُرجع مركز الثقل x/y ورقم المعرّف ودرجة الدوران لأكبر
# علامة AprilTag ضمن مجال رؤية كاميرا OpenMV.
#
# البيانات غير مستخدمة
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)),
    )


# عند استدعائها، تُرجع قائمة json من كائنات apriltag بصيغة json لجميع علامات apriltag ضمن مجال الرؤية.
#
# البيانات غير مستخدمة
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()


# عند استدعائها، تُرجع سلسلة المحتوى (payload) لأكبر رمز datamatrix
# ضمن مجال رؤية كاميرا OpenMV.
#
# البيانات غير مستخدمة
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 لجميع رموز datamatrix ضمن مجال الرؤية.
#
# البيانات غير مستخدمة
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()


# عند استدعائها، تُرجع سلسلة المحتوى (payload) لأكبر رمز شريطي (barcode)
# ضمن مجال رؤية كاميرا OpenMV.
#
# البيانات غير مستخدمة
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 لجميع الرموز الشريطية ضمن مجال الرؤية.
#
# البيانات غير مستخدمة
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.
#
# البيانات هي مجموعة عتبات تتبع الألوان المكونة من 6 بايتات: 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()  # لا توجد اكتشافات.
    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)


# عند استدعائها، تُرجع صورة مضغوطة بصيغة jpeg من كاميرا OpenMV
# في استدعاء RPC واحد.
#
# البيانات غير مستخدمة
def jpeg_snapshot(data):
    csi0.pixformat(csi.RGB565)
    csi0.framesize(csi.QVGA)
    img = csi0.snapshot()
    img.to_jpeg(quality=90)
    return img.bytearray()


# تسجيل دوال رد النداء (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)

# بمجرد تسجيل جميع دوال رد النداء، يمكننا البدء
# بمعالجة الأحداث البعيدة. لا تُرجع interface.loop() قيمة.

interface.loop()

results matching ""

    No results matching ""