學習目標:立創·廬山派K230CanMV開發板的進階學習——顏色識別
學習內容:顏色識別
顏色識別
1. 本節介紹
📝 學習內容:本節將學習基于顏色閾值的色塊檢測技術,通過定義特定顏色范圍,從攝像頭采集的圖像中識別并標記目標色塊,同時結合圖像繪制功能實現可視化指示。
🏆 學習目標:
- 掌握使用廬山派開發板尋找圖像色塊的方法;
- 理解顏色閾值的調節邏輯,提升顏色識別的準確性。
?? 注意事項:
- 顏色識別依賴顏色空間轉換與閾值匹配,需重點關注
LAB
色彩空間的參數設置; - 例程默認通過“立創·3.1寸屏幕擴展板”顯示,無屏幕時可在IDE緩沖區查看(可能因USB帶寬導致幀率低或卡頓)。
2. 顏色識別的基本原理
顏色識別通過以下核心步驟實現,廬山派內置圖像處理庫會自動完成中間關鍵環節,開發者僅需定義顏色范圍:
- 獲取圖像:通過攝像頭捕獲一幀畫面,轉換成數字信號,供算法處理。
- 顏色空間轉換:將圖像從默認的顏色空間(一般是RGB)轉換到適合分析的顏色空間(本節是LAB)。
- 閾值匹配:根據預先設定的顏色范圍,篩選出符合條件的像素。
- 區域分析:將相鄰的符合條件的像素組合成“區域”(Blob),并提取區域的特征(比如位置、大小、形狀等)。
- 標記與輸出:對識別出的區域進行標記,并輸出相關信息。
3. 什么是LAB色彩空間?
LAB
是基于人眼視覺感知設計的顏色空間,核心優勢是分離“亮度”與“顏色”信息,比RGB
更適合顏色識別。
3.1 RGB VS LAB
維度 | RGB色彩空間 | LAB色彩空間 |
---|---|---|
通道組成 | 紅(R)、綠(G)、藍(B)三通道 | 亮度(L)、紅-綠(A)、藍-黃(B)三通道 |
亮度與顏色關系 | 亮度與顏色信息混合,無法單獨分離 | 亮度(L)與顏色(A/B)完全分離 |
光照敏感性 | 光照變化會顯著影響RGB值,穩定性差 | 僅L通道受光照影響,A/B通道(顏色)魯棒性強 |
直觀性 | 人眼感知與RGB值無直觀關聯 | A/B通道直接對應顏色范圍,貼近人眼感知 |
色域范圍 | 設備相關(如sRGB僅覆蓋人眼可見色35%) | 設備無關,理論可表示所有人眼可見色 |
LAB通道詳解:
- L通道:亮度范圍
0-100
,0為純黑,100為純白; - A通道:顏色范圍
-128-127
,負值偏綠,正值偏紅; - B通道:顏色范圍
-128-127
,負值偏藍,正值偏黃。
3.2 關鍵提示
盡管LAB
對光照的魯棒性優于RGB
,但實際場景中環境光仍會影響識別效果:
- 需保證檢測環境的光照一致性(如避免強光直射或逆光);
- 調節閾值時,需在目標使用環境下進行,確保閾值匹配實際光照條件。
4. find_blobs
(尋找圖像中色塊)
find_blobs
是顏色識別的核心API,用于從圖像中篩選符合顏色閾值的色塊,并返回包含色塊特征的對象列表。
4.1 API原型
image.find_blobs(thresholds[, invert=False[, roi[, x_stride=2[, y_stride=1[, area_threshold=10[, pixels_threshold=10[, merge=False[, margin=0[, threshold_cb=None[, merge_cb=None]]]]]]]]]])
4.2 核心參數解釋
參數名 | 功能說明 |
---|---|
thresholds | 顏色閾值列表,格式為[(lo, hi), ...] :- 灰度圖:每個元組為 (最小灰度, 最大灰度) ;- RGB565圖(彩色):每個元組為 (L_min, L_max, A_min, A_max, B_min, B_max) ,對應LAB三通道范圍。 |
invert | 布爾值,True 時反轉閾值(僅匹配閾值外的像素),默認False 。 |
roi | 感興趣區域,格式(x, y, w, h) ,僅對該區域檢測,默認全圖。 |
area_threshold | 面積閾值,過濾掉邊界框面積小于此值的色塊(避免噪點誤識別)。 |
pixels_threshold | 像素閾值,過濾掉像素數量小于此值的色塊。 |
merge | 布爾值,True 時合并重疊的色塊,默認False 。 |
4.3 閾值獲取方法
通過CanMV IDE便捷獲取目標顏色的LAB
閾值:
- 在IDE幀緩沖區內單擊并拖動,框選目標顏色區域,直方圖會實時更新;
- 記錄直方圖中L、A、B通道的分布范圍,作為
thresholds
的參數; - 或通過IDE菜單“工具”→“機器視覺”→“閾值編輯器”,拖動滑塊可視化調節閾值。
5. 尋找特定顏色色塊(代碼示例)
以下代碼實現“識別特定顏色色塊并標記”的功能,以自定義LAB
閾值為例(可根據目標顏色調整):
import time, os, sys
from media.sensor import *
from media.display import *
from media.media import *sensor_id = 2
sensor = None# 顯示模式選擇:"VIRT"(虛擬)、"LCD"(3.1寸屏)、"HDMI"(HDMI擴展板)
DISPLAY_MODE = "LCD"# 根據顯示模式設置寬高
if DISPLAY_MODE == "VIRT":DISPLAY_WIDTH = ALIGN_UP(1920, 16)DISPLAY_HEIGHT = 1080
elif DISPLAY_MODE == "LCD":DISPLAY_WIDTH = 800DISPLAY_HEIGHT = 480
elif DISPLAY_MODE == "HDMI":DISPLAY_WIDTH = 1920DISPLAY_HEIGHT = 1080
else:raise ValueError("未知的 DISPLAY_MODE,請選擇 'VIRT', 'LCD' 或 'HDMI'")try:# 初始化攝像頭sensor = Sensor(id=sensor_id)sensor.reset()# 配置攝像頭參數:分辨率與像素格式(RGB565支持LAB轉換)sensor.set_framesize(width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, chn=CAM_CHN_ID_0)sensor.set_pixformat(Sensor.RGB565, chn=CAM_CHN_ID_0)# 初始化顯示器if DISPLAY_MODE == "VIRT":Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, fps=60)elif DISPLAY_MODE == "LCD":Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)elif DISPLAY_MODE == "HDMI":Display.init(Display.LT9611, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)# 初始化媒體管理器并啟動攝像頭MediaManager.init()sensor.run()# 1. 定義顏色閾值(LAB格式):[(L_min, L_max, A_min, A_max, B_min, B_max)]# 示例:識別偏紅的顏色(可根據目標顏色調整)color_threshold = [(0, 79, 31, 67, 26, 60)]while True:os.exitpoint() # 系統安全退出檢查# 2. 捕獲一幀圖像img = sensor.snapshot(chn=CAM_CHN_ID_0)# 3. 尋找色塊:過濾面積小于2000的色塊(避免噪點)blobs = img.find_blobs(color_threshold, area_threshold=2000)# 4. 標記色塊并輸出信息if blobs: # 若檢測到色塊for blob in blobs:# 繪制色塊外接矩形(blob[0:4] = [x, y, w, h])img.draw_rectangle(blob[0:4], color=(255, 0, 0), thickness=2)# 繪制色塊中心點十字(blob[5], blob[6] = 中心點x, y)img.draw_cross(blob[5], blob[6], color=(0, 255, 0), size=10, thickness=2)# 打印中心點坐標print(f"色塊中心:X={blob[5]}, Y={blob[6]}")# 5. 顯示處理后的圖像Display.show_image(img)except KeyboardInterrupt as e:print("用戶停止:", e)
except BaseException as e:print(f"異常:{e}")
finally:# 資源釋放if isinstance(sensor, Sensor):sensor.stop()Display.deinit()os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)time.sleep_ms(100)MediaManager.deinit()
5.1 代碼關鍵說明
- 顏色閾值配置:
color_threshold
需根據目標顏色的LAB
范圍調整,例如識別藍色時可設置為[(0, 50, -128, -20, -128, -30)]
; - 色塊過濾:
area_threshold=2000
過濾小面積噪點,可根據目標大小調整(如識別小物體時減小閾值); - 可視化標記:通過
draw_rectangle
和draw_cross
分別標記色塊邊界與中心點,便于直觀觀察。
5.2 效果優化建議
- 閾值微調:若出現“誤識別”(識別無關色塊),可縮小
LAB
通道范圍;若“漏識別”,可擴大范圍; - 設置ROI:通過
roi=(x, y, w, h)
限定檢測區域(如僅檢測畫面中心),減少干擾并提升效率; - 光照控制:在固定光照環境下調試閾值,避免強光、陰影等導致閾值失效。
6 如何進行閾值調節
首先運行一個能夠在幀緩沖區顯示圖像的程序,將廬山派的攝像頭對準你需要調節顏色閾值的對象,然后點擊幀緩沖區右上角的【禁用】,先把圖像固定,方便后續步驟。 位置如下圖所示:
注意
調節完閾值之后注意需要單擊這個【禁用】來取消,否則即使你重新運行程序,幀緩沖區也會一直不更新圖像。
單擊CanMV IDE K230上方菜單欄中的【工具】->【機器視覺】->【閾值編輯器】
在新彈出來的對話框中單擊【幀緩沖區】,設定圖像來源為幀緩沖區。
彈出來的框就是閾值編輯器,在下面的六個通道中來回拖動選定,需要注意的是左邊是原圖像,右邊圖像中展示為白色的就是我們要跟蹤的圖像。
首先需要確定你需要提取的顏色閾值范圍,我這里選定的是圖中的紅色,也就是左邊圖像中從上往下數的第三個方塊。上圖中的閾值范圍是我已經調節好的,我們如果要尋找紅色,其實就是讓右邊這個二進制圖像中顯示白色的位置和左邊的源圖像中的紅色位置是一致的。
在調節的過程中,要實時觀察右邊的二進制圖像。從默認的LAB值范圍開始,逐步縮小或擴大值的范圍,直到目標區域完全呈現為白色,背景為黑色。然后記錄最下面的LAB閾值,在這里是(0, 79, 31, 67, 26, 60),就是當前環境下我的屏幕上紅色的閾值。具體調節的效果可以看下面這個動圖:
學習時間:8月10日
1. 本節介紹
內容解讀
本節明確了學習核心是基于顏色閾值的色塊檢測技術,通過定義特定顏色范圍,從攝像頭圖像中識別并標記目標色塊,同時結合圖像繪制實現可視化。學習目標聚焦于兩點:掌握廬山派開發板尋找色塊的方法,以及理解顏色閾值調節邏輯以提升識別準確性。注意事項強調了LAB色彩空間參數設置的重要性,以及無屏幕時IDE緩沖區查看可能出現的幀率問題。
理解與感悟
這部分起到了提綱挈領的作用,讓學習者一開始就清楚學習的方向和重點。顏色識別的關鍵在于準確捕捉目標顏色的特征范圍,而LAB色彩空間在其中扮演重要角色,這提示我在后續學習中要重點關注該色彩空間的特性。同時,注意事項也很實用,提前告知了可能遇到的硬件相關問題,讓學習者有心理預期。
2. 顏色識別的基本原理
內容解讀
顏色識別的核心步驟包括獲取圖像、顏色空間轉換、閾值匹配、區域分析、標記與輸出。廬山派內置的圖像處理庫會自動完成中間關鍵環節,開發者只需定義顏色范圍。
理解與感悟
這個原理框架清晰地展現了顏色識別的流程。獲取圖像是基礎,就像人眼觀察事物一樣,首先要“看到”東西。顏色空間轉換則是將原始圖像信息轉換為更便于分析的形式,如同將一種語言翻譯成另一種更適合特定場景的語言。閾值匹配是篩選目標的關鍵,類似于設置一個標準,符合標準的才被選中。區域分析能將零散的符合條件的像素整合,便于整體研究。最后的標記與輸出則是將結果直觀呈現,讓我們能清晰看到識別效果。開發板內置庫簡化了中間步驟,讓開發者能更專注于顏色范圍的定義,降低了開發門檻。
3. 什么是LAB色彩空間?
3.1 RGB VS LAB
內容解讀
表格對比了RGB和LAB色彩空間的通道組成、亮度與顏色關系、光照敏感性、直觀性和色域范圍。LAB色彩空間中,L通道表示亮度(0-100),A通道表示紅-綠(-128-127,負值偏綠,正值偏紅),B通道表示藍-黃(-128-127,負值偏藍,正值偏黃)。
理解與感悟
通過對比,能明顯看出LAB色彩空間在顏色識別中的優勢。RGB的亮度和顏色信息混合,光照變化對其影響大,這會導致在不同光照條件下,同一顏色的RGB值可能差異很大,不利于穩定識別。而LAB將亮度和顏色分離,A、B通道受光照影響小,更能穩定地表示顏色特征,這也解釋了為什么本節要使用LAB色彩空間進行顏色識別。比如在實際場景中,同一紅色物體在強光和弱光下,其亮度會變化,但紅色的本質特征在A通道中能更穩定地體現,從而提高識別的準確性。
3.2 關鍵提示
內容解讀
盡管LAB對光照的魯棒性優于RGB,但實際場景中環境光仍會影響識別效果,需保證檢測環境光照一致性,且調節閾值時要在目標使用環境下進行。
理解與感悟
這提示我們理論優勢在實際應用中會受到環境因素的制約。即使LAB相對穩定,也不能完全忽視光照的影響。在實際開發中,要盡量為識別場景創造穩定的光照條件,比如避免強光直射、逆光等。同時,閾值調節必須結合實際使用環境,不能在實驗室調好后就一成不變,因為不同環境的光照差異可能導致閾值失效,這體現了理論聯系實際的重要性。
4. find_blobs
(尋找圖像中色塊)
4.1 API原型
內容解讀
給出了find_blobs
函數的原型,該函數用于從圖像中篩選符合顏色閾值的色塊,并返回包含色塊特征的對象列表。
理解與感悟
API原型是函數使用的基礎,它明確了函數的參數和返回值形式。對于開發者來說,熟悉原型是正確調用函數的前提,只有知道每個參數的含義和用法,才能根據實際需求進行合理設置。
4.2 核心參數解釋
內容解讀
表格解釋了thresholds
、invert
、roi
、area_threshold
、pixels_threshold
、merge
等核心參數的功能。其中thresholds
根據圖像類型有不同的格式,roi
用于限定檢測區域,area_threshold
和pixels_threshold
用于過濾噪點,merge
用于合并重疊色塊。
理解與感悟
這些參數的設置直接影響色塊識別的效果。thresholds
是核心中的核心,它決定了哪些顏色會被識別出來,其格式的不同要求也體現了函數的靈活性。roi
參數很實用,通過限定檢測區域,可以減少無關區域的干擾,提高識別效率,比如在一些特定場景中,我們只需要關注圖像的某個部分。area_threshold
和pixels_threshold
能有效過濾掉一些小的噪點色塊,避免誤識別,讓結果更準確。merge
參數則在處理多個重疊色塊時很有用,能將它們合并為一個整體進行分析。
4.3 閾值獲取方法
內容解讀
介紹了通過CanMV IDE獲取目標顏色LAB閾值的方法:在IDE幀緩沖區內框選目標顏色區域查看直方圖分布范圍,或通過“工具”→“機器視覺”→“閾值編輯器”可視化調節。
理解與感悟
這些方法為獲取準確的閾值提供了便利。手動框選區域查看直方圖能讓我們直觀地了解目標顏色在LAB各通道的分布范圍,而閾值編輯器的可視化調節更是降低了閾值設置的難度,通過實時觀察調節效果,能快速找到合適的閾值范圍,提高開發效率。
5. 尋找特定顏色色塊(代碼示例)
代碼結構分析
1. 初始化部分
sensor.reset() # 重置攝像頭
sensor.set_pixformat(sensor.RGB565) # 設置像素格式為RGB565
sensor.set_framesize(sensor.QVGA) # 設置幀大小為QVGA (320x240)
sensor.skip_frames(time=2000) # 跳過2秒,等待攝像頭穩定
這部分代碼完成了攝像頭的初始化工作:
sensor.reset()
是硬件復位操作,確保攝像頭處于初始狀態- 選擇RGB565格式是因為大多數圖像處理API都支持這種格式
- QVGA分辨率(320x240)在保證一定清晰度的同時,能減少計算量
- 等待2秒是為了讓攝像頭的自動曝光、白平衡等參數穩定下來
2. 顯示設備初始化
這部分代碼體現了開發板的靈活性,通過異常處理機制適配不同的顯示設備:
- 優先嘗試初始化LCD屏幕
- 失敗則嘗試HDMI顯示
- 最后使用虛擬顯示器(IDE中查看)
這種設計使得代碼可以在不同硬件配置下運行,提高了代碼的可移植性。
3. 顏色閾值定義
red_threshold = [(30, 100, 15, 127, 15, 127)] # 紅色的LAB閾值范圍
這是顏色識別的核心參數,每個閾值是一個六元組,分別代表:
- (L_min, L_max, A_min, A_max, B_min, B_max)
- 這里定義的是紅色的LAB范圍,實際應用中需要根據目標顏色調整
4. 主循環與色塊檢測
while True:img = sensor.snapshot() # 拍攝一幀圖像blobs = img.find_blobs(red_threshold, merge=True) # 尋找色塊
主循環中,程序不斷采集圖像并進行色塊檢測:
sensor.snapshot()
獲取當前幀圖像find_blobs()
是核心函數,參數說明:red_threshold
:要檢測的顏色閾值merge=True
:合并重疊或相鄰的色塊,避免同一物體被識別為多個色塊
5. 色塊處理與可視化
for blob in blobs:# 繪制矩形框住色塊img.draw_rectangle(blob.rect(), color=(0, 255, 0))# 在色塊中心繪制十字img.draw_cross(blob.cx(), blob.cy(), color=(0, 255, 0))
這部分實現了識別結果的可視化:
draw_rectangle()
用綠色矩形框出每個色塊draw_cross()
在色塊中心繪制十字標記- 這些可視化操作不影響原始圖像數據,僅用于展示
6. 色塊信息輸出
代碼打印了色塊的關鍵信息,這些信息在實際應用中非常有用:
- 位置坐標(x, y):色塊左上角位置
- 尺寸信息(w, h):色塊的寬度和高度
- 中心坐標(cx, cy):色塊中心點,可用于目標跟蹤
- 面積(area):色塊包含的像素數量,可用于判斷目標大小
關鍵技術點解析
-
顏色空間選擇:雖然代碼中設置的是RGB565格式,但
find_blobs
函數內部會自動將圖像轉換為LAB色彩空間進行處理,這也是為什么閾值需要用LAB格式定義。 -
閾值調節:代碼中使用的紅色閾值是示例值,實際應用中需要:
- 通過CanMV IDE的閾值編輯器獲取準確值
- 在實際使用環境中進行校準,考慮光照影響
-
性能優化:
- 使用QVGA分辨率而非更高分辨率,平衡識別精度和速度
merge=True
減少了后續處理的工作量- 適當的延時(
time.sleep_ms(100)
)降低系統負載
-
錯誤處理:顯示設備初始化部分使用了try-except結構,增強了代碼的健壯性。
實際應用擴展思路
- 多顏色識別:可以定義多個顏色閾值,如同時識別紅、綠、藍三種顏色
- 目標跟蹤:利用色塊中心坐標(cx, cy)實現簡單的目標跟蹤功能
- 尺寸過濾:通過面積(area)或寬高(w, h)過濾掉過小或過大的色塊,減少誤識別
- 區域限制:使用
roi
參數限定檢測區域,提高識別效率和準確性
這段代碼雖然簡單,但包含了顏色識別的核心流程,是實現更復雜機器視覺應用的基礎。在實際使用中,最關鍵的是根據具體場景調整顏色閾值和其他參數,以獲得最佳的識別效果。
6. 如何進行閾值調節
內容解讀
詳細介紹了閾值調節的步驟:運行程序在幀緩沖區顯示圖像并固定,通過CanMV IDE的閾值編輯器,設定圖像來源為幀緩沖區,拖動通道范圍使目標區域在二進制圖像中呈現白色,背景為黑色,最后記錄LAB閾值。
理解與感悟
閾值調節是顏色識別中非常關鍵的操作,直接影響識別的準確性。這個詳細的步驟指南讓初學者能夠輕松上手。固定圖像便于精確調節,閾值編輯器的可視化操作讓調節過程更加直觀,通過觀察二進制圖像中目標區域的變化,能快速找到最佳的閾值范圍。同時,注意調節后取消禁用幀緩沖區的提示也很重要,避免后續程序運行出現問題。這部分內容體現了開發工具的人性化設計,為開發者提供了便利。
學習總結:
通過對各章節的學習,我對基于立創·廬山派K230CanMV開發板的顏色識別技術有了全面的認識。從顏色識別的基本原理,到LAB色彩空間的優勢,再到find_blobs
函數的使用和閾值調節方法,形成了一個完整的知識體系。理論知識為實踐提供了指導,而代碼示例和操作步驟則讓理論得以落地。在實際應用中,需要綜合考慮光照條件、閾值設置、區域選擇等因素,不斷優化識別效果。這次學習不僅掌握了具體的技術,更體會到了理論與實踐相結合的重要性,以及在開發過程中不斷調試和優化的必要性。