v5.0.1#

الإصدار v5.0.1 هو إصدار صيانة فوق v5.0.0 — تصبح الوحدة القديمة sensor طبقة توافق Python فوق csi، وتُعايَن الصور المحمَّلة إلى مخزن الإطارات الآن مثل إطارات الكاميرا، وتتخلص مرمِّزات JPEG من حد الإخراج البالغ 1 MB وتتعامل مع الفيض بشكل صحيح، وهناك مجموعة من إصلاحات الكاميرا والبروتوكول والشبكات ومكتبة التعلم الآلي. لا يجلب أي تغييرات كاسرة للواجهة البرمجية للسكربتات المكتوبة لـ csi؛ والتغييرات السلوكية القليلة مدرجة تحت تغييرات الواجهة البرمجية الكاسرة.

أبرز النقاط#

  • الوحدة sensor أصبحت الآن وحدة Python مجمّدة مبنية على csi. تطبع تحذير إهمال عند الاستيراد؛ وبعض الدوال التي لا تستطيع الوحدة csi دعمها ترفع الآن OSError. انظر تغييرات وحدة sensor.

  • الصور المحمَّلة تُعايَن مثل إطارات الكاميرا. الصورة الموضوعة في مخزن الإطارات باستخدام copy_to_fb=True (image.Image و image.ImageIO.read() و fir.snapshot() و tof.snapshot()) تُدفع إلى الـ IDE — مع كل ما رُسم عليها — عندما تكتب الصورة التالية فوق مخزن الإطارات، بدلًا من دفعها فورًا. انظر تغييرات المعاينة.

  • إصلاح شامل لمرمِّز JPEG. زال حد مخزن الإخراج البالغ 1 MB (يُحدَّد حجم المخزن من الذاكرة الحرة)، ويُعالَج الفيض في كلا المسارين البرمجي والعتادي بدلًا من كتابة ملفات مبتورة، وحفظ صورة مضغوطة بالامتداد المضغوط الآخر يرفع استثناءً بدلًا من كتابة بيانات تالفة.

  • دالة جديدة protocol.poll() وستة عناصر واجهة CBOR جديدة (text و lineedit و pushbutton و spinbox و radio و waveform) لـ protocol.CBORChannel.

  • معالجة لاحقة لـ YOLO Pro، ودعم FLIR Lepton 3.1R / UW، وقراءات دفعية لـ IMU، وCAN على OpenMV N6، وهدف محاكاة قادر على الاتصال الشبكي.

ميزات جديدة#

  • YoloPro — معالجة لاحقة جديدة لنماذج كشف الكائنات YOLO Pro من Edge Impulse، بالإضافة إلى مثال yolo_pro_detector.py. (f3f150ebd, ea7bbb398)

  • protocol.poll() — تشغيل دورة واحدة من مهمة البروتوكول عند الطلب، لوسائل النقل المخصصة التي لا تقودها مقاطعة USB ولا مؤقت poll_ms. يمكن أيضًا استدعاء protocol.init() مرة أخرى لإعادة تهيئة الحزمة. (c00c215f9, f849ffb1b)

  • المزيد من عناصر واجهة قناة CBOR — يكتسب protocol.CBORChannel.add() العناصر text (سلسلة ثابتة) و lineedit (سلسلة قابلة للكتابة) و pushbutton (إجراء لحظي) و spinbox (إدخال رقمي بخطوات) و radio (مجموعة خيارات) و waveform (سلسلة زمنية أحادية البعد مع وسائط sample_rate و series و typecode؛ أسنِد بايتات عينات متداخلة لبثها). (8016d29ba)

  • csi.CUSTOM — يُرجع csi.CSI.framesize() الآن ثابتًا قابلًا للاستخدام بعد ضبط دقة (w, h) مخصصة، بدلًا من عدد صحيح مجهول. (af8841654)

  • قراءة دفعية لـ IMU — يقبل imu.__read_reg() مخزنًا مؤقتًا اختياريًا قابلًا للكتابة ويملؤه من سجلات متتالية في معاملة واحدة. (244ca480a)

  • FLIR Lepton 3.1R و Lepton UW يتعرف عليهما مشغّل Lepton، بما في ذلك أوضاع الكسب الراديومترية الخاصة بهما. (0fc356632)

  • الاتصال الشبكي في المحاكي — يتوفر هدف QEMU MPS2_AN500 الآن على lwIP وبطاقة شبكة في وضع المستخدم، مع تجميد requests و mqtt و sensor فيه، واختبار وحدة للشبكات. (23546dfb1, 61d187305, 15096c3a2)

  • مثال لواجهة برمجية متوافقة مع OpenAI — يلتقط openai_compatible.py صورة JPEG ويرسلها إلى نقطة نهاية chat-completions لوصف المشهد. (79033c6aa)

  • أمثلة SX126x LoRa — مشغّل lora-sx126x من micropython-lib (مع lora-sync / lora-async) مجمّد في البرنامج الثابت لـ OpenMV RT1062، مع أمثلة للمرسل/المستقبل/ping-pong/بث الصور لتوصيل وحدة SX1261 أو SX1262 بناقل SPI. هذا دعم مساهَم به من المجتمع؛ ولا تبيع OpenMV عتاد LoRa. (19576e1b1)

تغييرات وتحسينات أخرى#

  • إعادة كتابة مكتبة requests — تُفكَّك استجابات النقل المقطّع، ويُتاح وسيط timeout (الافتراضي 5 ثوانٍ)، وتُسلسل/تُرمَّز أجسام JSON والسلاسل النصية بشكل صحيح، وتُحلَّل الترويسات دون تمييز حالة الأحرف وسطر الحالة حسب الموضع، ويُنسخ قاموس headers الخاص بالمستدعي (بحيث لا يتسرب auth بعد الآن إلى الطلبات اللاحقة)، ويُقرأ الجسم على كتل في bytearray. (889f0b096)

  • يستورد mqtt الوحدة ssl بشكل كسول، لذا تعمل الوحدة والاتصالات العادية (غير TLS) على الإصدارات التي لا تدعم SSL. (c2e0899e8)

  • يُحدَّد حجم مخزن إخراج JPEG من الذاكرة الحرة بدلًا من حد ثابت قدره 1 MB؛ وتقلّص المرمِّزات المخزن إلى الحجم المرمَّز قبل كتابة الصورة، لذا لم تعد لقطات المستشعرات الكبيرة بجودة عالية تفشل. (aa1ca6776)

  • تنظيف المعالجة اللاحقة للتعلم الآلي — وُحِّد توليد الصناديق المحيطة عبر معالجات Darknet و Edge Impulse و Ultralytics اللاحقة، ويُبدَّل خرج YOLOv8 (transpose) بعد تطبيق العتبة بحيث يُخزَّن صفًا واحدًا لكل كشف مثل النماذج الأخرى. (b5c7853f2, c45f99cad)

  • إيقاف آمن لـ PAG7936 — راية إيقاف جديدة للمستشعر تُدخل PAG7936 في وضع السكون قبل تبديل RESET/PWDN، مما يصلح حالات التجمد عند استخدام المستشعر على كابل تمديد. كما يختار المشغّل مجموعة سجلات MIPI CSI-2 أو المتوازية من عنوان I2C للمستشعر في وقت التشغيل بدلًا من وقت البناء. (10026530c, f6acf14ec, 5f0251c74)

  • أصبح ضبط إيقاع تشغيل ImageIO يخدم الأحداث المعلقة أثناء انتظار الفاصل بين الإطارات بدلًا من السكون في WFI. (a54790193)

  • تحديثات الوحدة الفرعية MicroPython — دعم شبكي كامل على منفذ QEMU، و machine.mem_backup على STM32 عبر ذاكرة SRAM الاحتياطية/سجلات BKP، وإبقاء التحكم العتادي في تدفق SDIO معطلًا على STM32F4، وإعادة استخدام سمات MPU للمناطق غير القابلة للتخزين المؤقت. (31ada5626, ab61d27a6, 06bddf13a)

  • يلتقط differential-translation.py عبر كائن csi.CSI الخاص به بدلًا من الوحدة المهملة sensor، وجرى توحيد تباعد عبارات الاستيراد في الأمثلة. (68c866e7f, 9ceff4513)

إصلاحات الأخطاء#

الكاميرا والمستشعرات:

  • ضبط دقتين مخصصتين (w, h) على التوالي كان يترك المستشعر عند الحجم الأول بينما يبلّغ csi.CSI.width() / height() عن الثاني؛ أصبح المسار السريع "لا تغيير" يستثني الآن الأحجام المخصصة. (cfbb70156)

  • كان csi.CSI.lens_correction() يحلل radi و coef كقيم منطقية، لذا لم تكن القيم الممررة إلى المشغّل هي القيم المعطاة. (ab44b3a77)

  • PAG7936: ضبط التعريض والكسب تباعًا كان يُفسد أحدهما الآخر (كلاهما يشترك في وضع يدوي واحد وسجلات القراءة الخلفية تتأخر إطارًا)؛ أصبح المشغّل الآن يهيّئ السجلات اليدوية فقط عند الدخول في الوضع اليدوي ويكتب عنصر التحكم الذي يجري ضبطه فحسب. (e7a18c0a0)

  • كان التقاط BAYER من PAG7936 و PS5520 على OpenMV N6 يفشل بالخطأ "Failed to initialize the CSI interface" عند أي حجم غير الدقة الكاملة، لأن ISP في N6 لا يستطيع إعادة تحجيم Bayer الخام. تعمل المستشعرات الآن في وضع أصلي يطابق الحجم المطلوب لـ BAYER (PS5520: VGA و HD و SXGA-M و FHD و QHD و WQXGA2؛ أما QVGA فلا وضع أصلي له وهو غير مدعوم). (fe6790055, b7622b245)

ترميز الصور وحفظها:

  • مرمِّز JPEG البرمجي: كان فيض مخزن الإخراج قاتلًا دائمًا لأن مسار إعادة التخصيص كان معطلًا؛ أصبح الآن يوسّع المخزن (بمقدار نصف حجمه في كل مرة) عندما يملكه، ويتراجع بشكل نظيف عند نفاد الذاكرة، ويقلّص النتيجة. لم يعد jpeg_write / mjpeg_write يكتبان المخزن بعد فشل الترميز. (28e1110be)

  • مرمِّزات JPEG العتادية (STM32): كان الفيض يُرجع صورة مرمَّزة جزئيًا بحجم التخصيص، مما ينتج ملفات مبتورة دون علامة EOI (مثل لقطة 5 MP بجودة 100 نصفها السفلي فارغ). أصبحت الآن تبلّغ عن الفيض، وتحرر المخزن عند الفشل، وتقلّصه عند النجاح. (22ce9619c)

  • كان مرمِّز VC8000 ينتج بصمت صبغة 4:2:0 لكل طلب؛ أصبح أخذ العينات الفرعية بغير 4:2:0 يتراجع الآن إلى مرمِّز HW الذي يدعمه. (71f2be7f2)

  • كان image.Image.save() لصورة PNG بامتداد .jpg يكتب ما يصل إلى 1 MB من كومة غير مهيأة، ولصورة JPEG بامتداد .png يكتب ملفًا فارغًا. كلاهما يرفع استثناءً الآن؛ ولا تزال الصورة الموجودة أصلًا بالتنسيق الهدف تُنسخ كما هي. (6c1fdf822)

  • أصبح png_write يتحقق من القيمة المُعادة من الضاغط ويضغط قبل إنشاء الملف، لذا لم يعد الفشل يخلّف ملفًا فارغًا. (557f52d66)

وحدة الصور:

  • كان image.Image.get_pixel() مع rgbtuple=True على صور BAYER و YUV يكتب البكسل المحوَّل خارج متغير محلي في المكدس عند إزاحة يتحكم فيها المستدعي. (13f2a17b6)

  • أُسقط من gif.Gif.add_frame() فرع تحويل Bayer/YUV الذي لا يمكن الوصول إليه؛ لا تُقبل سوى صور GRAYSCALE و RGB565، كما كانت واجهة Python البرمجية تفرض بالفعل. (f20d99d96)

البروتوكول:

  • كان تسجيل قناة ديناميكية بينما كل الخانات مستخدمة بالفعل يسبب كتابة خارج الحدود؛ يُتحقق الآن من معرّف القناة أولًا، ويُتحقق بتأكيد ساكن من أن معرّفات القنوات المحجوزة تتسع في جدول القنوات. (68f635d1f)

  • كانت كائنات القنوات الديناميكية تبقى بعد إعادة الضبط البرمجية في مؤشرات الجذر، لذا كان جامع المهملات يواصل مسح كتل كومة قديمة من التشغيل السابق؛ يُمسح الجدول الآن عند التهيئة. (ef0ebb03b, e23641145)

المنافذ:

  • i.MX RT: أُضيف إلغاء تهيئة CAN و Encoder المفقود عند إعادة الضبط البرمجية. (7cb9d3dc2)

دعم العتاد واللوحات#

  • OpenMV N6 — أصبح CAN مفعّلًا الآن (machine.CAN). (294f0febd, 91e1c9573)

  • OpenMV AE3 — مشغّل SPI sdcard مجمّد فيه من أجل مقبس microSD على درع بطارية AE3. (a258f4814)

  • OpenMV RT1062 — lora-sx126x / lora-sync / lora-async مجمّدة فيه (انظر ميزات جديدة).

  • FLIR Lepton 3.1R / UW — يتعرف عليهما مشغّل Lepton على جميع اللوحات الداعمة لـ Lepton.

  • PAG7936 — إيقاف آمن، واختيار الواجهة في وقت التشغيل، وإصلاح التعريض/الكسب، والتقاط BAYER على N6.

  • PS5520 — التقاط BAYER على N6 بالأحجام الأصلية.

  • المحاكي (MPS2_AN500) — الاتصال الشبكي.

  • جميع اللوحات — وحدة التوافق sensor مجمّدة في بيان كل لوحة.

تغييرات الواجهة البرمجية الكاسرة#

لا يجلب v5.0.1 أي تغييرات كاسرة للواجهتين البرمجيتين csi أو image. السكربتات التي كانت تعمل على v5.0.0 تعمل دون تغيير، مع التغييرات السلوكية التالية.

وحدة sensor (سلوكي)#

أُزيلت الوحدة الأصلية sensor (modules/py_csi.c) واستُبدلت بوحدة Python مجمّدة تطبّق الواجهة البرمجية نفسها فوق csi. انظر sensor.

عملية التثبيت: 5e3d40631

  • يطبع import sensor الرسالة WARNING: The sensor module is deprecated and will be removed in a future release. Please use the csi module instead. في الطرفية.

  • يُنشأ كائن csi.CSI المخفي عند الاستيراد، لذا يرفع غياب الكاميرا الخطأ الآن عند import sensor بدلًا من sensor.reset().

  • ترفع هذه الدوال الآن OSError لأنه لا مكافئ لها في csi: get_fb() و alloc_extra_fb() و dealloc_extra_fb() و set_auto_rotation() و get_auto_rotation() و disable_delays() و disable_full_flush(). (كانت الدالتان *_extra_fb ترفعان بالفعل في v5.0.0.) استخدم csi.CSI(delays=False) / csi.CSI(fflush=False) للأخيرتين.

  • أحجام الإطارات التي لا تصدّرها csi (QQCIF و QQSIF و QQQQVGA و HQQQQVGA و HQQQVGA و HQQVGA و B64X32 و B64X64 و B128X64 و B128X128 و B160X160 و B320X320 و LCD و QQVGA2) أصبحت الآن صفوف (w, h) تُمرَّر كدقات مخصصة. يُرجع get_framesize() الصف الذي ضُبط ما دامت الكاميرا عند ذلك الحجم، بحيث تظل فحوصات المساواة مع الثوابت تعمل.

  • يمرّر ioctl() أربعة وسائط على الأكثر بعد الطلب.

  • يرفع sleep() / shutdown() الخطأ OSError عند الفشل كما في السابق (يُترجَم RuntimeError الخاص بـ csi).

رحّل إلى csi — انظر جدول ترحيل v5.0.0.

تحميل الصور إلى مخزن الإطارات (سلوكي)#

الدوال التي تحمّل صورة إلى مخزن الإطارات — image.Image مع copy_to_fb=True، و image.Image.copy() / image.Image.scale() وتحويلات to_* مع copy_to_fb=True، و image.ImageIO.read()، و fir.snapshot() و tof.snapshot() مع copy_to_fb=True — كانت تدفع الصورة الجديدة إلى معاينة الـ IDE فورًا، لذا لم يكن أي شيء يُرسم على الصورة المُعادة يظهر أبدًا. أصبحت الآن تعلّم مخزن الإطارات كمعلَّق وتدفعه، مع كل ما رُسم عليه، قبل أن تكتب الصورة التالية فوقه مباشرةً — وهو السلوك نفسه لـ csi.CSI.snapshot().

عمليات التثبيت: 87b6db5ee, 7b1a35c2f, f773c740d

الحلقات التي تقرأ تدفقًا من الصور لا تحتاج إلى أي تغيير وتُظهر رسمها الآن. أما السكربت الذي يحمّل صورة واحدة ثم يتوقف فيجب أن يدفعها صراحةً:

img = image.Image("example.bmp", copy_to_fb=True)
img.flush()          # new: send it to the IDE preview now
time.sleep_ms(1000)

مكتبة ML (سلوكي)#

يؤثر فقط على الشيفرة التي تشتق من المعالجات اللاحقة المرفقة أو تنسخها. يبدّل YoloV8 الآن خرج النموذج بعد تطبيق العتبة بحيث تُخزَّن الكشوف الباقية صفًا واحدًا لكل صندوق (bb[:, 4:])، بما يطابق معالجات Darknet و Edge Impulse اللاحقة، بدلًا من عمود واحد لكل صندوق (bb[4:, :]). النتائج العامة ((x, y, w, h), score) لم تتغير.

عمليات التثبيت: c45f99cad, b5c7853f2

وحدة protocol (ثانوي)#

عاد protocol.poll(). كان v5.0.0 قد أزاله عندما انتقلت مهمة البروتوكول إلى المؤقت؛ وهو يعود كطريقة صريحة لقيادة المهمة لوسائل النقل المخصصة. لم يتغير شيء آخر — السكربتات التي لم تستدعه قط لا تتأثر.

عملية التثبيت: c00c215f9

البناء / الأدوات (أدوات)#

لا يؤثر أي من هذا على سكربتات MicroPython. قُسّم py_image.c، مع انتقال كائنات الواصفات (cascade و keypoints و LBP و keypoint match) إلى py_image_descriptor.c وكائنات الإحصاءات (similarity و statistics و percentile و threshold و histogram) إلى py_image_stats.c. وُوئمت واجهة مرمِّز imlib البرمجية مع بقية imlib: يُرجع jpeg_compress / png_compress القيمة 0 عند النجاح و -1 عند الخطأ، وفقد jpeg_compress وسيطه realloc (إعادة التحجيم مشروطة بملكية المخزن). أصبح OMV_PROTOCOL_MAX_CHANNELS هو OMV_PROTOCOL_CHANNEL_MAX في omv_protocol_channel.h، وتستدعي المنافذ الآن py_protocol_init0() عند التهيئة. زال تعريف اللوحة OMV_PAG7936_MIPI_CSI2 (تُختار الواجهة في وقت التشغيل). وتكتمل الصورة بترقيات تبعيات CI وإصلاح لسجل تغييرات الإصدار الفارغ. انظر تاريخ مستودع البرنامج الثابت للتفاصيل ذات الصلة بالنسخ المتفرعة.

قائمة مراجعة الترحيل#

  • ما زلت تستخدم import sensor؟ يعمل، مع تحذير. انتقل إلى csi (ترحيل v5.0.0)؛ استبدل disable_delays / disable_full_flush بوسائط مُنشئ csi.CSI() وأزل استدعاءات get_fb / التدوير التلقائي.

  • تحمّل صورة واحدة باستخدام copy_to_fb=True وتتوقع رؤيتها؟ أضف img.flush() بعد التحميل.

  • نسخت معالجة YOLOv8 اللاحقة؟ فهرس الخرج بعد تطبيق العتبة حسب الصف (bb[:, 4:]) بدلًا من العمود.

  • تقارن csi0.framesize() بعد ضبط صف؟ يُرجع الآن csi.CUSTOM.

  • كل ما عدا ذلك: أعد تحميل البرنامج الثابت وشغّل.