在機器視覺中,將不同影像中的色彩成分分離是基本需求之一。 例如,這可能是指將 RGB 分解為其組成成分,但也包括將 HSL 或 XYZ 等色彩空間進行分離。 以下將展示一些色彩分離的範例。 所有範例均使用 RGB 面掃描相機作為輸入。 當然,這些範例同樣適用於線掃描相機。 此外,通常會先進行拜耳去馬賽克處理或色彩空間轉換,這些步驟亦可輕鬆加入範例中。
這些範例假設需要將分色資料傳輸至主機電腦進行後續處理。 因此,這些範例著重於分色 DMA 傳輸。 若您需要在 FPGA 中對分色資料進行處理,這些範例同樣可套用至您的需求。
以下列舉了幾個範例。 所有範例的結果都相同。 然而,各實現方式截然不同,且各有優缺點。 您需要選擇最符合您需求的範例。 下表列出了所有範例及其部分屬性。
| 範例名稱 | 延遲 | DRAM | 區塊 RAM 數量 | DMA 輸出 |
|---|---|---|---|---|
| 三個 DMA | 無額外延遲 | 1 個 DRAM 緩衝器 | 低 | 3 個 DMA。每種顏色成分各一個。 |
| 具 3 個緩衝區的序列式 | 延遲已降至理論上的最低值。 | 3 個 DRAM 緩衝器 | 低 | 1 DMA。依序輸出色彩成分。 |
| 具多區域興趣(MultiROI)緩衝區的序列式處理 | 1 幀延遲與頻寬限制。 | 1 個 DRAM 緩衝器 | 正常 | 1 DMA。依序輸出色彩成分。 |
| 具預先排序的多區域興趣(MultiROI)緩衝區的序列處理 | 1 幀延遲 | 1 個 DRAM 緩衝器 | 高 | 1 DMA。依序輸出色彩成分。 |
| 順序執行搭配進階緩衝區使用 | 1 幀延遲 | 1 個 DRAM 緩衝器 | 低 | 1 DMA。依序輸出色彩成分。 |
表 20. 色彩分離範例概覽
前一張表格中所列屬性的完整說明,以及各項方法的完整說明, 將於以下各節中闡述。
| 簡短描述 | |
|---|---|
|
檔案: \examples\Processing\Color\ColorPlaneSeparation\ColorPlaneSeparation_Option1_ThreeDMA.va |
![]() |
|
預設平台: mE5-MA-VCL |
|
|
簡短說明 RGB 色彩平面分離範例。 各色成分被分配至三個 DMA 輸出通道。 |
|
這個範例非常簡單。 輸入的 RGB 影像會先被緩衝,之後將色彩平面拆分為三個輸出連結。 這三個連結會透過三個DmaToPC運算子傳輸至 PC。 此解決方案的優勢在於,能將延遲降至最低。 影像不會在幀擷取卡中進行緩衝。 若主機電腦速度足夠快,ImageBuffer 運算子僅會使影像延遲一行。 不會產生額外的延遲。 另一項優勢是,僅需一個 DRAM 運算子即可。
此實現方式的一項缺點是,需要三個 DMA 輸出運算子。 這些運算子會消耗幀擷取卡大量的 FPGA 邏輯資源。 若您無需如此低的延遲,應考慮採用後續章節中提出的解決方案之一。
| 簡短描述 | |
|---|---|
|
檔案: \examples\Processing\Color\ColorPlaneSeparation\ColorPlaneSeparation_Option2_ThreeBuffersOneDMA.va |
![]() |
|
預設平台: mE5-MA-VCL |
|
|
簡短說明 RGB 色彩平面分離範例。 各組分被拆分並儲存於三個幀擷取器緩衝區中。 之後,透過一個 DMA 通道依序輸出各色彩平面。 |
|
在此 RGB 色彩平面分離的解決方案中,色彩平面會透過 DMA 通道依序輸出。 具體做法是將 RGB 輸入分解為其各組成部分,並分別將各色彩緩衝至三個 ImageBuffer 模組中。 透過運算子 InsertImage,將各色平面依序從ImageBuffer中讀取出來。
在此範例中,在將資料寫入ImageBuffer 之前,提高並行度至關重要。 否則,在InsertImage 模組之後將會出現瓶頸。
此方法的優點在於僅需一個 DMA 通道,從而減少了所需的資源。 此外,在順序輸出時,延遲可達到理論上的最低值。 紅色通道的 DMA 傳輸會立即開始,不會有任何延遲。 此解決方案的缺點在於需要三個影像擷取卡記憶體運算子。 由於這些運算子的數量有限,因此此解決方案僅在不需要更多此類緩衝區時才適用。
| 簡短描述 | |
|---|---|
|
檔案: \examples\Processing\Color\ColorPlaneSeparation\ColorPlaneSeparation_Option3_SequentialMultiROI.va |
![]() |
|
預設平台: mE5-MA-VCL |
|
|
簡短說明 RGB 色彩平面分離範例。 此處執行三種 RGB 色彩平面之序列式 DMA 輸出。 該序列由ImageBufferMultiRoI 產生。 此解決方案並不理想,因為它會限制頻寬。 請參閱下一個範例,以了解最佳化解決方案。 |
|
此解決方案是前一個範例與下一個範例之間的中間步驟。 由於頻寬限制,不建議實作此解決方案。 然而,它以簡單的方式說明了如何僅需一個幀 擷取器 RAM,即可獲得與前一個範例相同的輸出。 為了將影像序列化,我們使用ImageBufferMultiRoI 運算子。 在此運算子中,我們僅需讀取同一張影像三次。 接著,我們從第一張影像中選取紅色通道,從第二張影像中選取綠色通道,再從第三張影像中選取藍色通道。 這可透過ModuloCount和CASE運算子輕鬆實現。 ModuloCount經參數化後,會將幀號以 3 為模進行計數,即 {0, 1, 2, 0, 1, 2, ...}。
如前所述,此解決方案並非最佳方案,因為它會降低頻寬。 原因在於,我們雖然讀取了同一張輸入影像三次,但每次僅使用其中一個成分。 因此,在每個讀取週期中,我們都會捨棄三分之二的資料。 接下來的範例將展示一個類似的解決方案,該方案能克服此限制。
| 簡短描述 | |
|---|---|
|
檔案: \examples\Processing\Color\ColorPlaneSeparation\ColorPlaneSeparation_Option4_SequentialPreSortMultiROI.va |
![]() |
|
預設平台: mE5-MA-VCL |
|
|
簡短說明 RGB 色彩平面分離範例。 此處執行三組 RGB 色彩平面的順序式 DMA 輸出。 該順序由ImageBufferMultiRoI 產生。 透過額外的預先排序,可優化頻寬並解決前一範例中提出的問題。 |
|
此範例與前一個範例類似。 相較之下,此處並無頻寬限制。 其原理相同。 透過使用ImageBufferMultiRoI 運算子,我們將三個色通道依序處理。 與前一個範例不同,我們不會在緩衝區處理後再分離顏色。 而是將顏色在寫入緩衝區之前就進行分離。 這是在HierarchicalBoxPreSort 中完成的,其內容如以下圖所示。
此方法的原理是在將色彩成分寫入緩衝區之前,先將其分離。 此操作會針對每條影像行進行。 因此,我們將色彩成分拆分為三個連結。 這些產生的灰階連結現在包含輸入影像的各條影像行。 接著,這些影像行會被多工處理並追加。 最終結果是,我們將三張灰階影像整合成一張大型影像。 紅色成分位於左側,綠色位於中間,藍色位於右側。 請參閱下一圖中的模擬結果,以了解其實作方式。
在ImageBufferMultiRoI 中,我們現在必須先讀取左側部分。 接著讀取中間部分,最後讀取右側部分。 因此,我們需要為每個 ROI 設定不同的XOffset,如下所示。
使用時,請勿忘記如範例所示,在分離元件之前提高並行度。 這是為了避免在 InsertLine 模組之後產生瓶頸。 由於我們傳輸的是 8 位元灰階影像,而非 24 位元 RGB 影像,因此所需的並行度至少要比輸入高出三倍。
此解決方案確實僅需一名 DRAM 操作員,且不會限制頻寬。 這是經過優化的解決方案。 然而,需要一些區塊 RAM 來緩衝 FIFO 中分離的元件行。 對於小型影像而言,這不應造成問題。 然而,若影像寬度較大(例如每行 16384 像素),則需要大量區塊 RAM。 這個最後的缺點將在接下來的範例中解決。
| 簡短描述 | |
|---|---|
|
檔案: \examples\Processing\Color\ColorPlaneSeparation\ColorPlaneSeparation_Option5_SequentialAdvanced.va |
![]() |
|
預設平台: mE5-MA-VCL |
|
|
簡短說明 色彩平面分離的範例。 RGB 輸入資料會被拆分為各色成分,並透過單一 DMA 通道依序輸出。 拆分過程是透過將相同成分彙整至並行字元中,並使用FrameBufferRandomRead 進行讀取來實現的。 |
|
這是《VisualApplets 》中關於色彩平面分離的最先進範例。 其重點在於將資源使用量降至最低,並將頻寬提升至最高。 先前範例採用預先排序來分離色彩成分,以便我們能從 緩衝區中分別讀取這些成分。 然而,預先排序過程中的 FIFO 需要佔用部分區塊 RAM。 在此方法中,我們同樣採用預排序。 不同之處在於,我們僅在切換至下一色成分之前,先收集該色成分的 8 個連續像素。 在前一個範例中,我們是在收集完一個色成分的整行後,才切換至下一行。 此項修改使我們不再需要 FIFO。 然而,在此情況下無法使用ImageBufferMultiRoI。 取而代之,我們必須使用FrameBufferRandomRead。
預排序的步驟很簡單。 首先,我們將並行度提高到八。 接著,將各組分拆開。 這樣一來,便會產生三個鏈,每個鏈皆有八個並行元素。 MergeParallel 將把各組件中的八個像素排列成序列。 因此,我們將得到以下序列:R0 至 R7、G0 至 G7、B0 至 B7、R8 至 R15、G8 至 G15、B8 至 B15、……
由於PARALLELdn從 16 降至 8,因此輸入端必須設置 FIFO。 此 FIFO 僅用於避免觸發 DRC 2 級錯誤。 事實上,它無需緩衝資料,因此我們將其大小設定為僅 2 像素,非常小。
在對像素進行預先排序後,它們會被緩衝至FrameBufferRandomRead運算子中。 此運算子具有讀取列位址與列位址的輸入參數,並允許隨機讀取資料。
該運算子僅能搭配平行度為 1 的情況使用。 因此,我們使用CastParallel將平行度 8(每像素 8 位元)轉換為平行度 1(每像素 64 位元)。 這就是為什麼我們在上一步驟中收集了八個連續的像素。
為了分離色彩成分,我們必須將讀取位址增加兩,以跳過不需要的顏色。 因此,針對紅色成分,讀取位址將為:RColA(0) = 0, RColA(1) = 2, RColA(2) = 5, ... 至於綠色成分,讀取位址將為:RColA(0) = 1、RColA(1) = 3、RColA(2) = 6、... 階層式盒子「AdressGenerator」確實會產生這些讀取位址。 CreateBlankImage 運算子用於定義所需的影像尺寸。 由於我們先前已將CastParallel從 8 轉換為 1,因此必須使用影像寬度除以 8 的數值。
欄位位址的生成方式很簡單,只需將Coordinate_X的輸出值乘以 3 即可。 根據當前的元件,我們會向這些值加上 0、1 或 2 作為偏移量。
透過使用AppendImage,這三張位址圖像將被合併成一張較大的圖像。 行位址僅需透過一個介於 0 至圖像高度之間的計數器來產生。 在此情況下,我們使用ModuloCount運算子來執行此任務。 現在可以將這些位址傳入FrameBufferRandomRead運算子。 請勿忘記在CreatBlankImage輸出端設定並行度為 2,以充分發揮 FrameBufferRandomRead 的效能。
緩衝完成後,我們會得到一張大型影像,其中前幾行包含紅色影像,接著是綠色 影像,最後是藍色影像。 為了將這張大型影像分割成三個獨立的 DMA 輸出,我們使用SplitImage並設定影像高度。
要理解此實作,最簡單的方法是逐步檢視中間結果。 請注意,您需要模擬三個步驟才能得到一張結果圖像。 這是因為運算子 CreateBlankImage。
此解決方案在資源方面經過優化,因為僅需少量區塊 RAM 資源。 此外,FPGA 邏輯資源亦獲得高效利用。 位址產生僅需少量資源。












上一頁

