v5.0.1#

v5.0.1 היא מהדורת תחזוקה מעל v5.0.0 — המודול הישן sensor הופך לשכבת תאימות ב-Python מעל csi, תמונות שנטענו לחוצץ הפריימים מוצגות כעת בתצוגה המקדימה כמו פריימים מהמצלמה, מקודדי ה-JPEG משוחררים ממגבלת הפלט של 1 MB ומטפלים בגלישה כראוי, ויש אצווה של תיקונים למצלמה, לפרוטוקול, לרשת ולספריית ה-ML. היא אינה מביאה שום שינוי API שובר-תאימות לסקריפטים שנכתבו מול csi; קומץ שינויי ההתנהגות מפורטים תחת שינויי API שוברי-תאימות.

עיקרי הדברים#

  • המודול 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, ויעד simulator עם יכולת רשת.

תכונות חדשות#

  • 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 ו-NIC במצב משתמש, עם requests, mqtt ו-sensor קפואים פנימה, ובדיקת יחידה לרשת. (23546dfb1, 61d187305, 15096c3a2)

  • דוגמת API תואם-OpenAI — openai_compatible.py מצלם JPEG ושולח אותו ב-POST לנקודת קצה של chat-completions לתיאור הסצנה. (79033c6aa)

  • דוגמאות LoRa ל-SX126x — מנהל ההתקן lora-sx126x של micropython-lib (עם lora-sync / lora-async) קפוא לתוך קושחת OpenMV RT1062, עם דוגמאות שולח/מקבל/פינג-פונג/הזרמת-תמונה לחיווט מודול SX1261 או SX1262 לאפיק ה-SPI. זוהי תמיכה שנתרמה על ידי הקהילה; OpenMV אינה מוכרת חומרת LoRa. (19576e1b1)

שינויים ושיפורים נוספים#

  • שכתוב ספריית requests — תגובות בהעברה במקטעים (chunked) מפוענחות, ארגומנט timeout (ברירת מחדל 5 שניות) נחשף, גופי JSON ומחרוזות מסודרים/מקודדים כראוי, כותרות מנותחות ללא תלות ברישיות ושורת המצב לפי מיקום, המילון headers של הקורא מועתק (כך ש-auth כבר אינו דולף לבקשות מאוחרות יותר), והגוף נקרא בבלוקים לתוך bytearray. (889f0b096)

  • mqtt מייבא את ssl באופן עצל, כך שהמודול וחיבורים רגילים (ללא TLS) פועלים בבניות ללא תמיכת SSL. (c2e0899e8)

  • גודל חוצץ פלט ה-JPEG נקבע לפי הזיכרון הפנוי במקום תקרה קבועה של 1 MB; המקודדים קוצצים את החוצץ לגודל המקודד לפני כתיבת התמונה, כך שלכידות מחיישנים גדולים באיכות גבוהה כבר אינן נכשלות. (aa1ca6776)

  • ניקוי העיבוד-אחרי של ML — יצירת תיבות תוחמות אוחדה בין מעבדי-האחרי של Darknet, Edge Impulse ו-Ultralytics, ופלט YOLOv8 משוחלף (transposed) לאחר הסינון לפי סף כך שהוא מאוחסן בשורה אחת לכל זיהוי כמו שאר המודלים. (b5c7853f2, c45f99cad)

  • כיבוי בטוח של PAG7936 — דגל עצירה (halt) חדש של החיישן מרדים את ה-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 שהוצא משימוש, וריווח ה-import בדוגמאות נורמל. (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 תוכנתי: גלישת חוצץ הפלט הייתה תמיד פטאלית מכיוון שנתיב ה-realloc היה מושבת; כעת הוא מגדיל את החוצץ (בחצי מגודלו בכל פעם) כאשר הוא בבעלותו, נסוג בצורה נקייה כשהזיכרון אוזל, וקוצץ את התוצאה. jpeg_write / mjpeg_write כבר אינם כותבים את החוצץ לאחר קידוד שנכשל. (28e1110be)

  • מקודדי JPEG חומרתיים (STM32): גלישה החזירה תמונה מקודדת חלקית עם גודל ההקצאה, ויצרה קבצים קטועים ללא סמן EOI (למשל לכידה של 5 MP באיכות 100 עם חצי תחתון ריק). כעת הם מדווחים על גלישה, משחררים את החוצץ בכישלון וקוצצים אותו בהצלחה. (22ce9619c)

  • מקודד ה-VC8000 ייצר בשקט כרומה 4:2:0 עבור כל בקשה; תת-דגימה שאינה 4:2:0 נסוגה כעת לקודק החומרה שתומך בה. (71f2be7f2)

  • image.Image.save() של תמונת PNG בתור .jpg כתב עד 1 MB של ערימה לא מאותחלת, ושל תמונת JPEG בתור .png כתב קובץ ריק. שניהם מעוררים כעת חריגה; תמונה שכבר בפורמט היעד עדיין מועתקת כפי שהיא. (6c1fdf822)

  • png_write בודק כעת את ערך ההחזרה של הדוחס ודוחס לפני יצירת הקובץ, כך שכישלון כבר אינו משאיר אחריו קובץ ריק. (557f52d66)

מודול image:

  • image.Image.get_pixel() עם rgbtuple=True על תמונות BAYER ו-YUV כתב את הפיקסל המומר מעבר למשתנה מקומי במחסנית, בהיסט שנשלט על ידי הקורא. (13f2a17b6)

  • gif.Gif.add_frame() הסיר ענף המרה בלתי-נגיש של Bayer/YUV; מתקבלות רק תמונות GRAYSCALE ו-RGB565, כפי שה-API של Python כבר אכף. (f20d99d96)

פרוטוקול:

  • רישום ערוץ דינמי כאשר כל החריצים כבר בשימוש גרם לכתיבה מחוץ לגבולות; מזהה הערוץ נבדק כעת תחילה, ומזהי הערוצים השמורים נבדקים סטטית (static assert) כדי לוודא שהם נכנסים בטבלת הערוצים. (68f635d1f)

  • אובייקטי ערוצים דינמיים שרדו איפוס רך במצביעי השורש, כך שה-GC המשיך לסרוק בלוקי ערימה מיושנים מהריצה הקודמת; הטבלה מנוקה כעת באתחול. (ef0ebb03b, e23641145)

פורטים:

  • i.MX RT: נוסף ביטול האתחול החסר של CAN ו-Encoder באיפוס רך. (7cb9d3dc2)

תמיכת חומרה ולוחות#

  • OpenMV N6 — CAN מופעל כעת (machine.CAN). (294f0febd, 91e1c9573)

  • OpenMV AE3 — מנהל ההתקן sdcard ל-SPI קפוא פנימה עבור שקע ה-microSD שעל AE3 Battery Shield. (a258f4814)

  • OpenMV RT1062 — lora-sx126x / lora-sync / lora-async קפואים פנימה (ראו תכונות חדשות).

  • FLIR Lepton 3.1R / UW — מזוהים על ידי מנהל ההתקן של ה-Lepton בכל הלוחות התומכים ב-Lepton.

  • PAG7936 — עצירה לכיבוי בטוח, בחירת ממשק בזמן ריצה, תיקון חשיפה/הגבר, ולכידת BAYER על ה-N6.

  • PS5520 — לכידת BAYER על ה-N6 בגדלים נייטיב.

  • Simulator (MPS2_AN500) — רשת.

  • כל הלוחות — מודול התאימות sensor קפוא לתוך המניפסט של כל לוח.

שינויי API שוברי-תאימות#

v5.0.1 אינה מביאה שום שינוי שובר-תאימות ב-API של csi או של image. סקריפטים שרצו על v5.0.0 רצים ללא שינוי, עם שינויי ההתנהגות הבאים.

מודול sensor (behavior)#

המודול הנייטיב sensor (modules/py_csi.c) הוסר והוחלף במודול Python קפוא המממש את אותו API מעל csi. ראו sensor.

Commit: 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) הם כעת tuples מסוג (w, h) המועברים הלאה כרזולוציות מותאמות אישית. get_framesize() מחזיר את ה-tuple שהוגדר כל עוד המצלמה עדיין בגודל זה, כך שבדיקות שוויון מול הקבועים ממשיכות לעבוד.

  • ioctl() מעביר לכל היותר ארבעה ארגומנטים אחרי הבקשה.

  • sleep() / shutdown() מעוררים OSError בכישלון כמו קודם (ה-RuntimeError של csi מתורגם).

הגרו ל-csi — ראו את טבלת ההגירה של v5.0.0.

טעינת תמונות לחוצץ הפריימים (behavior)#

פונקציות שטוענות תמונה לחוצץ הפריימים — 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().

Commits: 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 (behavior)#

משפיע רק על קוד שיורש מהמעבדים-אחרי המצורפים או מעתיק אותם. YoloV8 משחלף כעת את פלט המודל לאחר הסינון לפי סף, כך שזיהויים ששרדו מאוחסנים לפי שורה אחת לכל תיבה (bb[:, 4:]), בהתאמה למעבדי-האחרי של Darknet ו-Edge Impulse, במקום עמודה אחת לכל תיבה (bb[4:, :]). התוצאות הציבוריות ((x, y, w, h), score) ללא שינוי.

Commits: c45f99cad, b5c7853f2

מודול protocol (minor)#

protocol.poll() חזר. v5.0.0 הסירה אותו כאשר משימת הפרוטוקול עברה לטיימר; הוא חוזר כדרך מפורשת להניע את המשימה עבור תעבורות מותאמות אישית. שום דבר אחר לא השתנה — סקריפטים שמעולם לא קראו לו אינם מושפעים.

Commit: c00c215f9

בנייה / כלים (tooling)#

דבר מכל זה אינו משפיע על סקריפטים של MicroPython. py_image.c פוצל, כאשר אובייקטי המתארים (cascade, keypoints, LBP, keypoint match) עברו ל-py_image_descriptor.c ואובייקטי הסטטיסטיקה (similarity, statistics, percentile, threshold, histogram) ל-py_image_stats.c. ה-API של מקודדי 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 ותיקון ל-changelog ריק של מהדורה משלימים את התמונה. ראו את היסטוריית מאגר הקושחה לפרטים הרלוונטיים ל-forks.

רשימת הגירה#

  • עדיין על 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() לאחר הגדרת tuple? הוא מחזיר כעת csi.CUSTOM.

  • כל השאר: צרבו מחדש והריצו.