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()จะไม่ส่งคืนการตรวจจับประเภทนี้