image --- 機器視覺

image 模組是 OpenMV 機器視覺堆疊的核心。它公開了 Image 類別(每個繪製、濾波、轉換與特徵擷取常式都會在其上運作的記憶體內像素緩衝區),並提供這些常式所回傳的結果物件(BlobLineCircleRectQRCodeAprilTagDataMatrixBarCode、...),以及用於設定這些常式的輔助類別(ThresholdHistogramStatisticsHaarCascadeSimilarityPercentileDisplacementImageIO)。

取得影像

有四種方式可將 Image 載入 RAM:

  • 從相機感測器即時擷取。 呼叫 csi.CSI.snapshot() 將下一個影格直接擷取至影格緩衝區;回傳的 Image 即參照該緩衝區。

  • 從檔案載入。 將路徑傳入 Image 建構子(image.Image("/sd/photo.jpg"));支援的磁碟格式為 BMP、PPM/PGM、JPEG、PNG 以及 OpenMV 的 ImageIO 錄製格式。

  • 從 ndarray 載入。 將 float32 的 (h, w)(h, w, 3) ndarray 傳入 Image 建構子。像素會從 0.0 -- 255.0 分別縮放為 GRAYSCALE 或 RGB565 影像。可藉此將 ml(或任何 ulab 管線)的張量輸出轉回可繪製的影像。

  • 空緩衝區。 以指定大小與像素格式建構 Imageimage.Image(320, 240, image.RGB565)),以便從零開始繪製,或作為影像算術運算的暫存表面。

像素格式

每個 Image 都具有下列像素格式之一;此選擇會在記憶體、處理成本以及可在其上執行的演算法之間取得平衡。在建構影像或設定相機感測器時,使用 BINARYGRAYSCALERGB565BAYERYUV422JPEGPNG 作為 pixformat 引數:

  • BINARY(1 bpp) -- 每像素一位元。最小的格式;由閾值化與形態學常式於內部使用,但很少直接從感測器擷取。

  • GRAYSCALE(8 bpp) -- 每像素一位元組(YUV422 的 Y 通道)。對大多數機器視覺演算法(AprilTag、邊緣偵測、光流)而言是最快的格式。

  • RGB565(16 bpp) -- 每像素兩位元組,5 位元紅 / 6 位元綠 / 5 位元藍。預設的色彩格式。

  • BAYER(8 bpp) -- 直接來自感測器的原始 Bayer 圖樣色彩資料。適用於自訂去馬賽克處理,或在需要時再進行去 Bayer 處理之前以較少記憶體儲存更多像素。

  • YUV422(16 bpp) -- 4:2:2 色度次取樣色彩,每像素兩位元組。當你想使用特定色度演算法而不需付出完整 RGB 成本時很有用。

  • JPEG / PNG -- 壓縮緩衝區。最適合用於儲存與網路傳輸。像素層級的操作需先使用 Image.to_grayscale()Image.to_rgb565()

處理結果

Image 上的偵測 / 特徵擷取方法會回傳可供你迭代與組合的物件 -- Image.find_blobs() 呼叫會回傳 Blob 清單,Image.find_apriltags() 呼叫會回傳 AprilTag 清單,以此類推。每個結果類別都會公開該偵測的幾何屬性(形心、邊界框、面積、碼值等),讓你可以直接對其操作,或將其傳回繪製方法(Image.draw_rectangle()Image.draw_string()、...)。

色彩空間輔助函式

本模組也公開了一些小型純函式,用於在二值 / 灰階 / RGB / LAB / YUV 色彩空間之間轉換個別像素值。當你需要在 Python 中先轉換閾值或調色盤項目,再將其傳入影像操作時,這些函式很有用 -- 若要進行全影像轉換,請使用 Imageto_* 方法,它們遠比在迴圈中呼叫這些輔助函式快得多。

類別

函式

色彩空間轉換輔助函式

下方每個 X_to_Y 函式都執行單一像素值的轉換。它們皆以 OpenMV 的標準範圍接收/回傳數值:

  • binary -- int 0 -- 1。

  • grayscale -- int 0 -- 255。

  • RGB -- 由 8 位元整數組成的 (r, g, b) 元組(每個 0 -- 255)。

  • LAB -- (l, a, b) 元組,其中 L 介於 0 -- 100,A/B 介於 -128 -- 127。

  • YUV -- (y, u, v) 元組,其中 Y 介於 0 -- 255,U/V 介於 -128 -- 127。

若要進行全影像轉換,請使用 Imageto_* 方法,它們遠比在迴圈中呼叫這些輔助函式快得多。

image.binary_to_grayscale(value: int) int

將二值值轉換為灰階值。

image.binary_to_rgb(value: int) Tuple[int, int, int]

將二值值轉換為 RGB 元組。

image.binary_to_lab(value: int) Tuple[int, int, int]

將二值值轉換為 LAB 元組。

image.binary_to_yuv(value: int) Tuple[int, int, int]

將二值值轉換為 YUV 元組。

image.grayscale_to_binary(value: int) int

將灰階值轉換為二值值。

image.grayscale_to_rgb(value: int) Tuple[int, int, int]

將灰階值轉換為 RGB 元組。

image.grayscale_to_lab(value: int) Tuple[int, int, int]

將灰階值轉換為 LAB 元組。

image.grayscale_to_yuv(value: int) Tuple[int, int, int]

將灰階值轉換為 YUV 元組。

image.rgb_to_binary(value: Tuple[int, int, int]) int

將 RGB 元組轉換為二值值。

image.rgb_to_grayscale(value: Tuple[int, int, int]) int

將 RGB 元組轉換為灰階值。

image.rgb_to_lab(value: Tuple[int, int, int]) Tuple[int, int, int]

將 RGB 元組轉換為 LAB 元組。

image.rgb_to_yuv(value: Tuple[int, int, int]) Tuple[int, int, int]

將 RGB 元組轉換為 YUV 元組。

image.lab_to_binary(value: Tuple[int, int, int]) int

將 LAB 元組轉換為二值值。

image.lab_to_grayscale(value: Tuple[int, int, int]) int

將 LAB 元組轉換為灰階值。

image.lab_to_rgb(value: Tuple[int, int, int]) Tuple[int, int, int]

將 LAB 元組轉換為 RGB 元組。

image.lab_to_yuv(value: Tuple[int, int, int]) Tuple[int, int, int]

將 LAB 元組轉換為 YUV 元組。

image.yuv_to_binary(value: Tuple[int, int, int]) int

將 YUV 元組轉換為二值值。

image.yuv_to_grayscale(value: Tuple[int, int, int]) int

將 YUV 元組轉換為灰階值。

image.yuv_to_rgb(value: Tuple[int, int, int]) Tuple[int, int, int]

將 YUV 元組轉換為 RGB 元組。

image.yuv_to_lab(value: Tuple[int, int, int]) Tuple[int, int, int]

將 YUV 元組轉換為 LAB 元組。

特徵描述子

image.HaarCascade(path: str, stages: int = -1) Cascade

載入 Haar Cascade 並回傳一個 Cascade 控制代碼,供 Image.find_features() 使用。

path 可以是下列其中之一:

  • 字面字串 "frontalface""eye",用於載入烘焙至韌體 ROM 中的兩個 cascade 之一,或

  • 由 OpenMV cascade 轉換工具產生的自訂 .cascade 二進位檔的檔案系統路徑。

stages 用於選擇偵測時要評估多少個 cascade 階段。-1 會使用檔案中儲存的每一個階段。降低此值可加快偵測速度,但代價是更多誤判。

image.load_descriptor(path: str) kp_desc | lbp_desc

path 處的檔案載入描述子並回傳。檔案的內部類型標籤會決定要重建哪一個描述子類別:

image.save_descriptor(descriptor: kp_desc | lbp_desc, path: str) None

以 OpenMV 描述子檔案格式將 descriptor(ORB 關鍵點或 LBP 描述子)序列化至 path 處的檔案。日後可透過 image.load_descriptor() 重新載入同一檔案。

image.match_descriptor(descriptor0, descriptor1, threshold: int = 85, filter_outliers: bool = False) int | kptmatch

比對兩個相同類型的描述子。

  • 對於兩個 LBP 描述子 -- 回傳它們之間的整數漢明距離(越低代表越接近的比對)。

  • 對於兩個 ORB 關鍵點描述子 -- 回傳一個描述已比對關鍵點群集的 kptmatch,若沒有任何比對通過 threshold 則回傳 None

threshold(0 -- 100)設定接受關鍵點配對時 ORB 比對的嚴格程度。較低的值會藉由拒絕較弱的最近鄰比對而使比對更嚴格。

filter_outliers 啟用跨整組已比對關鍵點的 RANSAC 式離群值剔除。當你預期兩個視角之間存在單一剛性變換時可使用它;當已比對關鍵點橫跨多個物件時則停用它。

色塊幾何輔助函式

這些輔助函式接收一個 Blob(如 Image.find_blobs() 所回傳),並按需計算額外的幾何屬性。它們位於模組範圍 -- 而非 Blob 上 -- 因此除非你主動要求,基本的 find_blobs() 路徑不會為它們付出成本。

image.get_solidity(blob: blob) float

回傳 blob 的密實度(blob.pixels / convex_hull_area)。浮點數,0 -- 1;1.0 表示色塊完全填滿其凸包。

image.get_convexity(blob: blob) float

回傳 blob 的凸度(convex_hull_perimeter / blob.perimeter)。浮點數,0 -- 1;1.0 為完美的凸形色塊。

image.get_major_axis_line(blob: blob) line

回傳沿著 blob 長軸的 Line(最小面積旋轉矩形兩個主軸中較長者)。

image.get_minor_axis_line(blob: blob) line

回傳沿著 blob 短軸的 Line(最小面積旋轉矩形兩個主軸中較短者)。

image.get_enclosing_circle(blob: blob) circle

回傳一個包圍 blobCircle

image.get_enclosed_ellipse(blob: blob) Tuple[int, int, int, int, int]

回傳一個 5 元組 (cx, cy, a, b, rotation),描述內接於 blob 周圍最小面積旋轉矩形的橢圓:

  • cx / cy -- 橢圓中心(以像素為單位,整數)。

  • a / b -- 半軸長度(以像素為單位,整數)。

  • rotation -- 橢圓旋轉以度為單位(整數)。

這是普通元組而非 attrtuple,因此各欄位僅能透過索引存取。

常數

像素格式

可將下列任一者作為 pixformat 引數傳入 Image 建構子或 csi.CSI.pixformat()

image.BINARY: int

每像素 1 位元的點陣圖。最小的格式 -- 由閾值化與形態學於內部使用,很少直接從感測器擷取。

image.GRAYSCALE: int

每像素 8 位元的灰階(每像素一位元組)。對大多數機器視覺演算法(AprilTag、邊緣偵測、光流)而言是最快的格式。

image.RGB565: int

每像素 16 位元色彩,封裝為 5 位元紅 / 6 位元綠 / 5 位元藍。預設的色彩格式。

image.BAYER: int

直接來自感測器的每像素 8 位元原始 Bayer 資料。大多數影像處理方法無法用於 Bayer 影像;當你想按需進行去 Bayer 處理,或以較少記憶體儲存更多像素時使用它。

image.YUV422: int

4:2:2 色度次取樣色彩,每像素兩位元組,每個像素配對封裝為 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()

色彩調色盤

可將下列任一者傳入 Image.to_rainbow()Image.to_ironbow()Image.draw_image()color_palette=)或 csi.CSI.color_palette(),以為灰階影像著色。

image.PALETTE_RAINBOW: int

平滑的彩虹色環。OpenMV 用於熱影像的預設調色盤。

image.PALETTE_IRONBOW: int

非線性的「ironbow」調色盤,模仿 FLIR Lepton 熱像取景器的外觀。

image.PALETTE_DEPTH: int

深度影像調色盤。僅在具備深度感測器支援的版本(ToF 管線 -- 例如 OpenMV Cam AE3 或任何外接 ToF Pmod 的相機)上可用。

image.PALETTE_EVT_DARK: int

用於在深色背景上將 GENX320 事件相機影格視覺化的調色盤。將其傳入 csi.CSI.color_palette 可讓 GENX320 驅動程式在直方圖模式下輸出已著色的 RGB565 影格,或在為灰階事件影像著色時將其傳入 Image.draw_image()color_palette=

僅在具備 GENX320 支援的版本(OpenMV Cam AE3 與 GENX320 Pmod)上可用。

image.PALETTE_EVT_LIGHT: int

用於在淺色背景上將 GENX320 事件相機影格視覺化的調色盤。其分派與可用性與 PALETTE_EVT_DARK 相同。

縮放模式

可將下列任一者作為 hint 引數傳入 Image.draw_image()Image.scale() 或類似的縮放方法。

image.AREA: int

區域平均縮放器。用於縮小時;放大時則使用最近鄰法。

image.BILINEAR: int

雙線性縮放器。縮小時會進行次取樣。

image.BICUBIC: int

雙三次縮放器。品質高於 BILINEAR 但較慢。縮小時會進行次取樣。

繪製 / draw_image 提示

可將下列任意項目以位元 OR 組合在一起,並作為 Image.draw_image()hint 引數傳入。

image.VFLIP: int

繪製時垂直翻轉來源。

image.HMIRROR: int

繪製時水平鏡像來源。

image.TRANSPOSE: int

繪製時轉置(交換 x/y)來源。

image.CENTER: int

將來源置中於目的地。任何明確的 x/y 偏移量隨後將變為相對於中心的偏移量,而非相對於左上角。

image.EXTRACT_RGB_CHANNEL_FIRST: int

當透過 Image.draw_image() 擷取 RGB 通道時,在縮放之前擷取通道。若不使用此提示,則於縮放之後擷取通道。

image.APPLY_COLOR_PALETTE_FIRST: int

當透過 Image.draw_image() 套用色彩調色盤時,在縮放之前套用調色盤。若不使用此提示,則於縮放之後套用調色盤。

image.SCALE_ASPECT_KEEP: int

將來源縮放至適配目的地內部,同時維持長寬比(比例不同時加上黑邊)。

image.SCALE_ASPECT_EXPAND: int

將來源縮放至填滿目的地,同時維持長寬比(比例不同時進行裁切)。

image.SCALE_ASPECT_IGNORE: int

將來源縮放至填滿目的地,忽略長寬比。

image.BLACK_BACKGROUND: int

告知 alpha 混合路徑目的地已知為黑色,因此可略過目的地像素的回讀。可加快在剛清除過的緩衝區上的 alpha 效果。

image.ROTATE_90: int

VFLIP | TRANSPOSE 的捷徑(順時針旋轉 90 度)。

image.ROTATE_180: int

HMIRROR | VFLIP 的捷徑(旋轉 180 度)。

image.ROTATE_270: int

HMIRROR | TRANSPOSE 的捷徑(順時針旋轉 270 度)。

JPEG 次取樣

在寫入 JPEG 時,可將下列任一者作為 subsampling 引數傳入 Image.to_jpeg()Image.compress()Image.save()

image.JPEG_SUBSAMPLING_AUTO: int

根據 JPEG 品質設定自動選擇色度次取樣。

image.JPEG_SUBSAMPLING_444: int

強制使用 4:4:4 色度次取樣(無色度壓縮)。

image.JPEG_SUBSAMPLING_422: int

強制使用 4:2:2 色度次取樣。當串流 MJPEG 至無法正確處理 4:2:0 的第三方影片播放器時建議使用。

image.JPEG_SUBSAMPLING_420: int

強制使用 4:2:0 色度次取樣。

範本比對

可將下列任一者作為 search 引數傳入 Image.find_template()

image.SEARCH_EX: int

窮舉搜尋 -- 評估 ROI 中的每個位置。最慢但保證能找到最佳比對。

image.SEARCH_DS: int

鑽石搜尋 -- 由粗到細的搜尋,遠比 SEARCH_EX 快,但在高度自相似的範本上可能會錯過全域最佳解。

邊緣偵測

可將下列任一者作為 algorithm 引數傳入 Image.find_edges()

image.EDGE_CANNY: int

Canny 邊緣偵測器 -- 梯度量值 + 非極大值抑制 + 遲滯。品質較高,較慢。

image.EDGE_SIMPLE: int

閾值化高通濾波器邊緣偵測器。較快但產生比 EDGE_CANNY 更粗、更雜訊的邊緣。

ORB 角點偵測器

可將下列任一者作為 corner_detector 引數傳入 Image.find_keypoints()

image.CORNER_FAST: int

FAST 角點偵測器。比 CORNER_AGAST 快但較不準確。

image.CORNER_AGAST: int

AGAST 角點偵測器。比 CORNER_FAST 慢但產生更穩定的關鍵點。

AprilTag 系列

可將下列任意組合以位元 OR 組合,並作為 families 引數傳入 Image.find_apriltags()。每個系列在韌體中皆由其各自的建置選項所控制;不支援的系列在執行階段會直接不存在,而非永遠為零。

image.TAG16H5: int

AprilTag 16h5 系列(30 個唯一 ID,0 位元錯誤校正)。

image.TAG25H9: int

AprilTag 25h9 系列(35 個唯一 ID,最多 3 位元錯誤校正)。

image.TAG36H10: int

AprilTag 36h10 系列(2320 個唯一 ID,最多 3 位元錯誤校正)。

image.TAG36H11: int

AprilTag 36h11 系列(587 個唯一 ID,最多 4 位元錯誤校正)。最常見的系列。

image.TAGCIRCLE21H7: int

AprilTag Circle21h7 系列。

image.TAGCIRCLE49H12: int

AprilTag Circle49h12 系列。

image.TAGCUSTOM48H12: int

AprilTag Custom48h12 系列。

image.TAGSTANDARD41H12: int

AprilTag Standard41h12 系列。

image.TAGSTANDARD52H13: int

AprilTag Standard52h13 系列。

條碼符號系統

Image.find_barcodes() 回傳的項目於 BarCode.type 中所回報的值。

image.EAN2: int

EAN-2 補充條碼。

image.EAN5: int

EAN-5 補充條碼。

image.EAN8: int

EAN-8 條碼。

image.UPCE: int

UPC-E 條碼。

image.ISBN10: int

ISBN-10 條碼。

image.UPCA: int

UPC-A 條碼。

image.EAN13: int

EAN-13 條碼。

image.ISBN13: int

ISBN-13 條碼。

image.I25: int

交錯式 2-of-5 條碼。

image.DATABAR: int

GS1 DataBar 條碼。

image.DATABAR_EXP: int

GS1 DataBar Expanded 條碼。

image.CODABAR: int

Codabar 條碼。

image.CODE39: int

Code 39 條碼。

image.PDF417: int

PDF417 二維堆疊條碼。此常數為求完整而存在,但條碼解碼器目前並未實作 PDF417 -- Image.find_barcodes() 不會回傳此類型的偵測結果。

image.CODE93: int

Code 93 條碼。

image.CODE128: int

Code 128 條碼。