image --- การมองเห็นของเครื่อง#
โมดูล image คือหัวใจของกลุ่มฟังก์ชันการมองเห็นของเครื่อง OpenMV โมดูลนี้เปิดเผยคลาส Image ซึ่งเป็นบัฟเฟอร์พิกเซลในหน่วยความจำที่ทุกฟังก์ชันวาด กรอง แปลง และดึงลักษณะเด่นทำงานด้วย รวมถึงออบเจกต์ผลลัพธ์ที่ฟังก์ชันเหล่านั้นส่งคืน (Blob, Line, Circle, Rect, QRCode, AprilTag, DataMatrix, BarCode, ...) และคลาสตัวช่วยสำหรับกำหนดค่า (Threshold, Histogram, Statistics, HaarCascade, Similarity, Percentile, Displacement, ImageIO)
การรับภาพ#
มีสี่วิธีในการโหลด Image เข้าสู่ RAM:
ถ่ายสดจาก camera sensor เรียก
csi.CSI.snapshot()เพื่อถ่ายเฟรมถัดไปลงในบัฟเฟอร์เฟรมโดยตรง โดยImageที่ส่งคืนจะอ้างอิงไปยังบัฟเฟอร์นั้นจากไฟล์ ส่งพาธไปยังคอนสตรักเตอร์
Image(image.Image("/sd/photo.jpg")) รูปแบบไฟล์บนดิสก์ที่รองรับ ได้แก่ BMP, PPM/PGM, JPEG, PNG และรูปแบบบันทึกImageIOของ OpenMVจาก ndarray ส่ง
ndarrayแบบ float32 ขนาด(h, w)หรือ(h, w, 3)ไปยังคอนสตรักเตอร์Imageพิกเซลจะถูกปรับสเกลจาก0.0 -- 255.0เป็นภาพ GRAYSCALE หรือ RGB565 ตามลำดับ ใช้วิธีนี้เพื่อนำผลลัพธ์ tensor จากml(หรือ pipeline ใดๆ ของulab) กลับมาเป็นภาพที่วาดได้บัฟเฟอร์เปล่า สร้าง
Imageด้วยขนาดและรูปแบบพิกเซลที่กำหนด (image.Image(320, 240, image.RGB565)) เพื่อวาดตั้งแต่ต้น หรือใช้เป็น scratch surface สำหรับการคำนวณภาพ
รูปแบบพิกเซล#
Image ทุกรูปมีรูปแบบพิกเซลอย่างใดอย่างหนึ่งต่อไปนี้ การเลือกรูปแบบจะแลกเปลี่ยนระหว่างหน่วยความจำ ต้นทุนการประมวลผล และอัลกอริทึมที่ใช้ได้ ใช้ BINARY, GRAYSCALE, RGB565, BAYER, YUV422, JPEG หรือ PNG เป็นอาร์กิวเมนต์ pixformat เมื่อสร้างภาพหรือกำหนดค่า camera sensor:
BINARY (1 bpp) -- หนึ่งบิตต่อพิกเซล รูปแบบที่เล็กที่สุด ใช้ภายในโดยฟังก์ชันการกำหนดค่าขีดแบ่งและ morphology แต่แทบไม่ได้ถ่ายจาก sensor โดยตรง
GRAYSCALE (8 bpp) -- หนึ่งไบต์ต่อพิกเซล (ช่อง Y ของ YUV422) รูปแบบที่เร็วที่สุดสำหรับอัลกอริทึม computer-vision ส่วนใหญ่ (AprilTag, การตรวจจับขอบ, optical flow)
RGB565 (16 bpp) -- สองไบต์ต่อพิกเซล สีแดง 5 บิต / สีเขียว 6 บิต / สีน้ำเงิน 5 บิต รูปแบบสีเริ่มต้น
BAYER (8 bpp) -- ข้อมูลสีแบบ Bayer-pattern ดิบที่มาโดยตรงจาก sensor เหมาะสำหรับการ de-mosaic แบบกำหนดเองหรือเก็บพิกเซลได้มากขึ้นในหน่วยความจำน้อยลงก่อน debayer ตามต้องการ
YUV422 (16 bpp) -- สีแบบ 4:2:2 chroma-subsampled สองไบต์ต่อพิกเซล เหมาะเมื่อต้องการอัลกอริทึมที่เจาะจง chroma โดยไม่เสียต้นทุนเต็มของ RGB
JPEG / PNG -- บัฟเฟอร์ที่บีบอัด เหมาะที่สุดสำหรับการจัดเก็บและส่งผ่านเครือข่าย การดำเนินการระดับพิกเซลต้องเรียก
Image.to_grayscale()หรือImage.to_rgb565()ก่อน
การทำงานกับผลลัพธ์#
เมธอดการตรวจจับ/ดึงลักษณะเด่นใน Image ส่งคืนออบเจกต์ที่สามารถวนซ้ำและรวมกันได้ เช่น การเรียก Image.find_blobs() ส่งคืนรายการ Blob, การเรียก Image.find_apriltags() ส่งคืนรายการ AprilTag และอื่นๆ คลาสผลลัพธ์แต่ละคลาสเปิดเผยคุณสมบัติทางเรขาคณิตของการตรวจจับ (จุดศูนย์กลาง, กรอบล้อมรอบ, พื้นที่, ค่าโค้ด ฯลฯ) เพื่อให้ดำเนินการได้โดยตรงหรือส่งกลับไปยังเมธอดวาด (Image.draw_rectangle(), Image.draw_string(), ...)
ตัวช่วยสี#
โมดูลยังเปิดเผยฟังก์ชัน pure เล็กๆ สำหรับแปลงค่าพิกเซลแต่ละค่าระหว่างพื้นที่สี binary / grayscale / RGB / LAB / YUV ฟังก์ชันเหล่านี้มีประโยชน์เมื่อต้องแปลงค่าขีดแบ่งหรือรายการ palette ใน Python ก่อนส่งเข้าสู่การดำเนินการภาพ สำหรับการแปลงทั้งภาพให้ใช้เมธอด to_* ของ Image ซึ่งเร็วกว่าการเรียกฟังก์ชันตัวช่วยเหล่านี้ในลูปมาก
คลาส#
- คลาส Image -- วัตถุภาพ
- class ImageIO -- ImageIO object
- class HaarCascade -- Feature Descriptor
- class Similarity -- Similarity Object
- class Histogram -- Histogram Object
- class Percentile -- Percentile Object
- class Threshold -- Threshold Object
- class Statistics -- Statistics Object
- class Blob -- Blob object
- class Line -- Line object
- class Circle -- Circle object
- class Rect -- Rectangle Object
- class QRCode -- QRCode object
- class AprilTag -- ออบเจ็กต์ AprilTag
- class DataMatrix -- DataMatrix object
- class BarCode -- BarCode object
- class Displacement -- Displacement object
- class kptmatch -- Keypoint match object
ฟังก์ชัน#
ฟังก์ชันตัวช่วยแปลงพื้นที่สี#
ฟังก์ชัน X_to_Y แต่ละตัวด้านล่างทำการแปลงค่าพิกเซลเดียว ทั้งหมดรับ/ส่งคืนค่าในช่วงมาตรฐาน OpenMV:
binary --
int0 -- 1grayscale --
int0 -- 255RGB --
(r, g, b)tuple ของจำนวนเต็ม 8 บิต (แต่ละค่า 0 -- 255)LAB --
(l, a, b)tuple โดยLอยู่ใน 0 -- 100 และA/Bอยู่ใน -128 -- 127YUV --
(y, u, v)tuple โดยYอยู่ใน 0 -- 255 และU/Vอยู่ใน -128 -- 127
สำหรับการแปลงทั้งภาพให้ใช้เมธอด to_* ของ Image ซึ่งเร็วกว่าการเรียกฟังก์ชันตัวช่วยเหล่านี้ในลูปมาก
ตัวบ่งชี้ลักษณะเด่น#
- image.HaarCascade(path: str, stages: int = -1) Cascade#
โหลด Haar Cascade และส่งคืนหมายเลขอ้างอิง
Cascadeสำหรับใช้กับImage.find_features()pathอาจเป็น:สตริงตัวอักษร
"frontalface"หรือ"eye"เพื่อโหลด cascade หนึ่งในสองที่ฝังอยู่ใน firmware ROM หรือพาธในระบบไฟล์ไปยังไฟล์ไบนารี
.cascadeที่สร้างด้วยเครื่องมือ cascade-converter ของ OpenMV
stagesเลือกจำนวน cascade stage ที่จะประเมินเมื่อตรวจจับ-1ใช้ทุก stage ที่เก็บอยู่ในไฟล์ การลดค่านี้จะเร่งความเร็วการตรวจจับแต่เพิ่ม false positive มากขึ้น
- image.load_descriptor(path: str) kp_desc | lbp_desc#
โหลด descriptor จากไฟล์ที่
pathและส่งคืน แท็กประเภทภายในของไฟล์จะเลือกว่าจะสร้าง descriptor class ใดขึ้นมาใหม่:ORB keypoint descriptor -- บันทึกโดย
Image.find_keypoints()ตามด้วยimage.save_descriptor()LBP descriptor -- บันทึกโดย
Image.find_lbp()ตามด้วยimage.save_descriptor()
- image.save_descriptor(descriptor: kp_desc | lbp_desc, path: str) None#
บันทึก
descriptor(ORB keypoint หรือ LBP descriptor) ลงในไฟล์ที่pathในรูปแบบไฟล์ descriptor ของ OpenMV ไฟล์เดิมสามารถโหลดใหม่ได้ภายหลังผ่านimage.load_descriptor()
- image.match_descriptor(descriptor0, descriptor1, threshold: int = 85, filter_outliers: bool = False) int | kptmatch#
จับคู่ descriptor สองตัวที่มีประเภทเดียวกัน
สำหรับ LBP descriptor สองตัว -- ส่งคืนค่าระยะ Hamming แบบจำนวนเต็มระหว่างสองตัว (ค่าน้อยกว่าหมายถึงคู่ที่ใกล้เคียงกว่า)
สำหรับ ORB keypoint descriptor สองตัว -- ส่งคืน
kptmatchที่อธิบาย keypoint cluster ที่จับคู่กัน หรือNoneหากไม่มีคู่ที่ผ่านthreshold
threshold(0 -- 100) กำหนดความเข้มงวดในการจับคู่ ORB เมื่อยอมรับคู่ keypoint ค่าน้อยจะเพิ่มความเข้มงวดโดยปฏิเสธการจับคู่เพื่อนบ้านที่ใกล้ที่สุดที่อ่อนแอfilter_outliersเปิดใช้งานการปฏิเสธ outlier แบบ RANSAC ในชุด keypoint ที่จับคู่กัน ใช้เมื่อคาดหวัง rigid transform เดียวระหว่างมุมมองทั้งสอง ปิดเมื่อ keypoint ที่จับคู่กันครอบคลุมหลายออบเจกต์
ตัวช่วยเรขาคณิตสำหรับ blob#
ตัวช่วยเหล่านี้รับ Blob (ที่ส่งคืนโดย Image.find_blobs()) และคำนวณคุณสมบัติทางเรขาคณิตเพิ่มเติมตามต้องการ ฟังก์ชันเหล่านี้อยู่ที่ระดับโมดูล ไม่ใช่บน Blob ดังนั้น path พื้นฐาน find_blobs() จะไม่เสียต้นทุนจากฟังก์ชันเหล่านี้ เว้นแต่จะเรียกใช้
- image.get_solidity(blob: blob) float#
ส่งคืนความเป็นของแข็ง (
blob.pixels / convex_hull_area) ของblobเป็น Float ช่วง 0 -- 1 โดย 1.0 หมายความว่า blob เต็มรูปร่าง convex hull โดยสมบูรณ์
- image.get_convexity(blob: blob) float#
ส่งคืนความนูน (
convex_hull_perimeter / blob.perimeter) ของblobเป็น Float ช่วง 0 -- 1 โดย 1.0 คือ blob ที่นูนอย่างสมบูรณ์
- image.get_major_axis_line(blob: blob) line#
ส่งคืน
Lineตามแกนหลักของblob(แกนที่ยาวกว่าในสองแกนหลักของสี่เหลี่ยมหมุนที่มีพื้นที่น้อยที่สุด)
- image.get_minor_axis_line(blob: blob) line#
ส่งคืน
Lineตามแกนรองของblob(แกนที่สั้นกว่าในสองแกนหลักของสี่เหลี่ยมหมุนที่มีพื้นที่น้อยที่สุด)
- image.get_enclosed_ellipse(blob: blob) Tuple[int, int, int, int, int]#
ส่งคืน 5-tuple
(cx, cy, a, b, rotation)ที่อธิบายวงรีที่บรรจุอยู่ในสี่เหลี่ยมหมุนที่มีพื้นที่น้อยที่สุดรอบblob:cx/cy-- จุดศูนย์กลางของวงรีในพิกเซล (จำนวนเต็ม)a/b-- ความยาวกึ่งแกนในพิกเซล (จำนวนเต็ม)rotation-- การหมุนของวงรี เป็นองศา (จำนวนเต็ง)
นี่คือ tuple ธรรมดา ไม่ใช่ attrtuple ดังนั้นสามารถเข้าถึงฟิลด์ได้โดยดัชนีเท่านั้น
ค่าคงที่#
รูปแบบพิกเซล#
ส่งค่าใดๆ ต่อไปนี้เป็นอาร์กิวเมนต์ pixformat ไปยังคอนสตรักเตอร์ Image หรือไปยัง csi.CSI.pixformat()
- image.BINARY: int#
bitmap 1 บิตต่อพิกเซล รูปแบบที่เล็กที่สุด ใช้ภายในโดยการกำหนดค่าขีดแบ่งและ morphology แทบไม่ถ่ายโดยตรงจาก sensor
- image.GRAYSCALE: int#
ระดับสีเทา 8 บิตต่อพิกเซล (หนึ่งไบต์ต่อพิกเซล) รูปแบบที่เร็วที่สุดสำหรับอัลกอริทึม computer-vision ส่วนใหญ่ (AprilTag, การตรวจจับขอบ, optical flow)
- image.RGB565: int#
สี 16 บิตต่อพิกเซล บรรจุเป็นสีแดง 5 บิต / สีเขียว 6 บิต / สีน้ำเงิน 5 บิต รูปแบบสีเริ่มต้น
- image.BAYER: int#
ข้อมูล Bayer ดิบ 8 บิตต่อพิกเซลที่มาโดยตรงจาก sensor เมธอดการประมวลผลภาพส่วนใหญ่ไม่สามารถใช้กับภาพ Bayer ได้ ใช้รูปแบบนี้เมื่อต้องการ debayer ตามต้องการหรือเก็บพิกเซลได้มากขึ้นในหน่วยความจำน้อยลง
- image.YUV422: int#
สีแบบ 4:2:2 chroma-subsampled สองไบต์ต่อพิกเซล บรรจุเป็น
Y1, U, Y2, Vต่อคู่พิกเซล มีเพียงบางเมธอดการประมวลผลภาพที่ทำงานโดยตรงบน YUV422
- image.JPEG: int#
บัฟเฟอร์ JPEG ที่บีบอัด การดำเนินการระดับพิกเซลต้องเรียก
Image.to_grayscale()หรือImage.to_rgb565()ก่อน
- image.PNG: int#
บัฟเฟอร์ PNG ที่บีบอัด การดำเนินการระดับพิกเซลต้องเรียก
Image.to_grayscale()หรือImage.to_rgb565()ก่อน
Color palettes#
ส่งค่าใดๆ ต่อไปนี้ไปยัง Image.to_rainbow(), Image.to_ironbow(), Image.draw_image() (color_palette=) หรือไปยัง csi.CSI.color_palette() เพื่อใส่สีให้กับภาพระดับสีเทา
- image.PALETTE_IRONBOW: int#
palette "ironbow" แบบไม่เชิงเส้นที่เลียนแบบลักษณะของช่องมองภาพความร้อน FLIR Lepton
- image.PALETTE_DEPTH: int#
palette สำหรับภาพเชิงลึก มีให้ใช้เฉพาะบน build ที่รองรับ depth-sensor (ToF pipeline เช่น OpenMV Cam AE3 หรือ cam ที่มี ToF Pmod)
- image.PALETTE_EVT_DARK: int#
Palette สำหรับแสดงเฟรมจากกล้อง event GENX320 บนพื้นหลังมืด ส่งไปยัง
csi.CSI.color_paletteเพื่อให้ GENX320 driver ส่งออกเฟรม RGB565 ที่ใส่สีในโหมด histogram หรือส่งไปยังImage.draw_image()color_palette=เมื่อใส่สีให้กับภาพ event ระดับสีเทามีให้ใช้เฉพาะบน build ที่รองรับ GENX320 (OpenMV Cam AE3 และ GENX320 Pmod)
- image.PALETTE_EVT_LIGHT: int#
Palette สำหรับแสดงเฟรมจากกล้อง event GENX320 บนพื้นหลังสว่าง การส่งและความพร้อมใช้งานเหมือนกับ
PALETTE_EVT_DARK
โหมดสเกล#
ส่งค่าใดๆ ต่อไปนี้เป็นอาร์กิวเมนต์ hint ไปยัง Image.draw_image(), Image.scale() หรือเมธอดสเกลที่คล้ายกัน
hints การวาด / draw_image#
นำค่าใดๆ เหล่านี้มา Bit-OR กันแล้วส่งเป็นอาร์กิวเมนต์ hint ของ Image.draw_image()
- image.CENTER: int#
จัดต้นทางให้อยู่ตรงกลางของปลายทาง ออฟเซต x/y ที่ระบุไว้จะกลายเป็นออฟเซตจากจุดกลางแทนที่จะเป็นจากมุมบนซ้าย
- image.EXTRACT_RGB_CHANNEL_FIRST: int#
เมื่อดึงช่อง RGB ผ่าน
Image.draw_image()ให้ดึงช่อง ก่อน สเกล หากไม่มี hint นี้ ช่องจะถูกดึงหลังจากสเกล
- image.APPLY_COLOR_PALETTE_FIRST: int#
เมื่อใช้ color palette ผ่าน
Image.draw_image()ให้ใช้ palette ก่อน สเกล หากไม่มี hint นี้ palette จะถูกใช้หลังจากสเกล
- image.SCALE_ASPECT_KEEP: int#
สเกลต้นทางให้พอดีภายในปลายทางโดยรักษาสัดส่วน (เพิ่มแถบดำเมื่อสัดส่วนต่างกัน)
JPEG subsampling#
ส่งค่าใดๆ ต่อไปนี้เป็นอาร์กิวเมนต์ subsampling ไปยัง Image.to_jpeg(), Image.compress() หรือ Image.save() เมื่อเขียน JPEG
Template matching#
ส่งค่าใดๆ ต่อไปนี้เป็นอาร์กิวเมนต์ search ไปยัง Image.find_template()
การตรวจจับขอบ#
ส่งค่าใดๆ ต่อไปนี้เป็นอาร์กิวเมนต์ algorithm ไปยัง Image.find_edges()
- image.EDGE_CANNY: int#
Canny edge detector -- ขนาดกราเดียนต์ + non-max suppression + hysteresis คุณภาพสูงกว่า ช้ากว่า
- image.EDGE_SIMPLE: int#
ตัวตรวจจับขอบแบบ high-pass-filter ที่ผ่านค่าขีดแบ่ง เร็วกว่าแต่ให้ขอบที่หนาและมีสัญญาณรบกวนมากกว่า
EDGE_CANNY
ตัวตรวจจับมุม ORB#
ส่งค่าใดๆ ต่อไปนี้เป็นอาร์กิวเมนต์ corner_detector ไปยัง Image.find_keypoints()
- image.CORNER_FAST: int#
FAST corner detector เร็วกว่า
CORNER_AGASTแต่แม่นยำน้อยกว่า
- image.CORNER_AGAST: int#
AGAST corner detector ช้ากว่า
CORNER_FASTแต่ให้ keypoint ที่เสถียรกว่า
ตระกูล AprilTag#
นำค่าใดๆ ต่อไปนี้มา Bit-OR รวมกันแล้วส่งเป็นอาร์กิวเมนต์ families ไปยัง Image.find_apriltags() แต่ละตระกูลถูกควบคุมโดย build option ของตนเองใน firmware ตระกูลที่ไม่รองรับจะไม่ปรากฏเมื่อ runtime แทนที่จะเป็นศูนย์เสมอ
สัญลักษณ์บาร์โค้ด#
ค่าที่รายงานใน BarCode.type สำหรับรายการที่ส่งคืนโดย Image.find_barcodes()
- image.PDF417: int#
บาร์โค้ด PDF417 2D แบบซ้อน ค่าคงที่นี้มีไว้เพื่อความครบถ้วน แต่ตัวถอดรหัสบาร์โค้ดยังไม่รองรับ PDF417 ขณะนี้
Image.find_barcodes()จะไม่ส่งคืนการตรวจจับประเภทนี้