縮放線掃描影像

簡要說明

檔案: \examples\Processing\Geometry\ScalingLine\ScalingLineP16.va
\examples\Processing\Geometry\ScalingLine\ScalingLineP8.va

預設平台: mE5-MA-VCL

短說明

線掃描影像的 Scaling 與轉換

VisualApplets 設計「ScalingLineP8.va」與「ScalingLineP16.va」會以任意倍數對 CameraLink Full 組態中的灰階線掃描相機影像進行 Scaling,以轉換輸入與輸出之間的影像寬度。「ScalingLineP8.va」適用於 Parallelism 為 8,而 「ScalingLineP16.va」適用於 marathon VCL 平台的 Parallelism 為 16。 本文件說明 VisualApplets 中的演算法與實作。若要使用此設計,需要計算許多尋找表 (lookup table) 數值。 內含的 C++ 與 Matlab 程式可提供這些計算以簡化使用方式。

行中Scaling/轉換的基本概念

線影像的 Scaling / 轉換 / Distortion Correction 是根據來源與目標影像座標來執行的。 接下來將以範例座標對與 Parallelism 4 來解說演算法的 基本原理。

目標座標: 0 1 2 3 | 4 5 6 7 | 8 9 10 11 | 12 13 14 15
來源座標: 0.3 0.5 1.4 1.5 | 2.2 3.4 3.6 4.2| 5.4 5.5 7.8 8.5 | 9.1 11.4 13.3 14.1

我們使用 Target-To-Source 程序。對於目標影像中的每個像素(= 傳送至 PC 的輸出影像),我們都會選擇對應的 (四捨五入)整數座標 以及來源影像中的對應像素值。像素之間的 posicao 位置會透過同時選取目前像素座標在 來源影像中的前一個像素鄰近點來考量。透過線性插值即可計算出輸出影像中的正確像素值。 由於 Parallelism 的緣故,無法從來源影像讀取單一像素。因此,必須以實用的順序讀取「字組」(同時讀取的像素單位)。 可能會發生必須讀取字組多次或完全不需要讀取的情況。在從來源 影像讀取的這些字組中,必須選取用於 建立輸出字組的正確像素位置。將刪除讀取字組中不需要的像素。以下範例 說明來自來源影像座標的讀取存取:

記憶體讀取計數循環 要求的目標座標 各自的來源座標 讀取字組 / 含像素 使用字組中的像素
1 0, 1 2, 3 0.3, 0.5, 1.4, 1.5 0/ 0, 1, 2, 3 1, 1, 2, 2
2 4 2.2 0/ 0, 1, 2, 3 3, x, x, x
3 5, 6, 7, 8 3.4, 3.6, 4.2, 5.4 1/ 4, 5, 6, 7 4, 4, 5, 6
4 9 5.5 1/ 4, 5, 6, 7 6, x, x, x
5 10, 11, 12 7.8, 8.5, 9.1 2/ 8, 9, 10, 11 9, 8, 10, x
6 13, 14, 15 11.4, 13.3, 14.1 3 / 12, 13, 14, 15 12, 14, 15, x

表 24. 讀取循環


同時「x」表示該像素已被刪除。

在 VisualApplets 中實作

此設計的主要元件為(圖 335):

1. 連接至線掃描相機的介面,包含觸發系統與緩衝區;
2. 相機影像的 Scaling(位於 Transformation);
3. 至 PC 的 DMA 資料傳輸;

Scaling 線掃描相機影像的基本設計結構

圖 335. Scaling 線掃描相機影像的基本設計結構


接下來我們將詳細說明主要元件 Transformation。

Transformation

您可以查看 變換 的組成部分,請參見圖336。

轉型的組成要素

圖 336.轉換的組成部分


相機線掃描影像的縮放是透過「目標至來源」程序進行的。 在 WordToRead 中,我們會選擇以何種 順序從輸入 相機影像中讀取 8 個 (「ScalingLineP8.va」中並行度為 8)或 16 個(「ScalingLineP16.va」中並行度為 16)像素(=「字」)的單位。在 PixelPicker 中,我們決定從讀取的「字」中需要哪些像素。 插值 在計算 輸出影像中的像素值時,會考量來源影像中像素間的位置關係。

WordToRead

圖337 顯示了 WordToRead 模組的組成部分。

WordToRead 的組成部分

圖 337.WordToRead的組成部分


從原始圖像中讀取單字的順序與頻率,定義於 LUT: WordsToRead中定義。此 表格的內容是透過外部 C++ 程式「ScalingLUTS.cpp」或替代方案——MATLAB 模組「LUTS_Scaling.m」 及「ScalingTablelLine.m」所建立。 相關詳情請參閱本文件中的 節。此查找表的輸入連結是透過 CreateBlankImage 以及 Coordinate_X。參數 ImageWidth 的 CreateBlankImage 的參數ImageWidth的值,必須與 LUT:WordsToRead中的元素數完全相同。參數 ImageHeight 必須與來源影像在 y 方向上的尺寸相符。來源影像中的文字會從 緩衝區 LineMemoryRandomRd_1 和 LineMemoryRandomRd_2中讀取, 中讀取,其順序由 LUT:WordsToRead所定義的順序中讀取。來源影像會以線性方式寫入這些緩衝區。由於最大位元 深度為 64 位元且並行度為 1,因此需要兩個緩衝區。對於每個字,會選取並讀取前一個字的最後一個像素(位於 操作行上方的 SYNC)選取並讀取前一字的最後一個像素(位於SYNC 之前的上層 運算行)。此值會透過運算子 Merge運算子,將其加到對應的字中。

PixelPicker

在該模組中 PixelPicker (參見圖338)中,用於縮放後 輸出字元的像素是透過元件 Pick_0 至 Pick_15 (或至 Pick_7 並行度為 8)從讀取的字元中選取。若讀取的字元中的像素無需使用(參見 節) 則查表 RemovePixel 會將其刪除。上述表(Pick_0 至 Pick_15 及 RemovePixel)的內容,可透過外部 C++ 程式「ScalingLUTS.cpp」建立,或改用 MATLAB 模組 「LUTS_Scaling.m」與「ScalingTablelLine.m」。相關詳情請參閱本文件中 一節。

PixelPicker 的組成元件

圖 338.PixelPicker的組成元件


在圖339中,HierarchicalBox 的內容 Pick_0 的內容。該 查表 PickComponent0 定義了從(SelectFromParallel: Word 和 Coordinate_X: 數值)中的哪個像素是當前輸出單字的第 0 個分量。透過運算子 CASE 運算子 將選取對應的像素。該像素將與其前一個像素合併後寫入當前像素(MergePixel)。類似於上述 所述程序,透過 模組 Pick_1 至 Pick_15 (或至 Pick_7)。單一像素 Pick_0 至 Pick_15 (或至 Pick_7) 會以 16 或 8 的並行度與當前經轉換/縮放後的單詞進行合併 (MergeParallel ,如圖338 所示)。

Pick_0 的內容

圖 339.Pick_0的內容


Interpolation

為了在傳送至電腦的輸出影像中,獲得像素位置的正確數值,必須考量 原始影像中的像素間位置。 在此模組中 「插值」 模組(圖336)中,會執行線性插值 [Bur06]:

方程式 30。


此處 是輸出影像中的像素值, 該值對應於 在原始圖像中 位於位置 x。此外 和 是位於像素座標處的數值 和 在原始影像中。像素間的位置是 . 有關線性插值的更多資訊, 您可參閱例如 [Bur06]。

模組的內容 Interpolation 的完整內容如圖 340。 目前像素的值 及其 前一個像素 使用運算子進行分隔 SelectBitField: Current 和 SelectBitField: Previous。以下項目的值 和 與以下項目相乘 和 根據公式 30。關於像素間位置的資訊 包含在四個查找表中 Fractional_Part0 設定為 Fractional_Part3 位於設計「ScalingLineP16.va」中。每個表格針對目前輸出字的 4 個像素包含像素間位置 。 每個像素間位置具有 6 bit 位元深度。LUT 的內容 Fractional_Part0 設定為 Fractional_Part3 可以使用外部 C++ 程式「ScalingLUTS.cpp」建立,或者改用 MATLAB 模組「LUTS_Scaling.m」與 「ScalingTablelLine.m」建立。關於這部分,亦請參閱 本文件中的 節。 設計「ScalingLineP8.va」有一個包含像素間位置的表格 Fractional。其內容也可以透過外部 C++ 和 Matlab 程式模組來建立。 最後,轉換/縮放後的線形影像會透過 DMA 傳輸發送至 PC(請參閱圖 336)。

插補元件

圖 340。Interpolation 的元件


VisualApplets 設計的對照表 (Lookup Tables)

設計「ScalingLineP16.va」和「ScalingLineP8.va」所需的查找表(請參閱 節)可以使用 C++ 程式 “ScalingLUTs.cpp”(位於「LUTS_Cpp」資料夾中)或 MATLAB 程式模組「LUTS_Scaling.m」與「ScalingTableLine.m」(位於 「LUTS_MATLAB」資料夾中)來建立。

ScalingLUTs.cpp

1. 請在程式(或命令提示字元)中定義下列參數:

//////////////////////Parameter////////////////////

/ 請指定這些參數!////////// /

uint64_t parallelism = 8; // =8 代表「ScalingLineP8.va」,=16 代表「ScalingLineP16.va」

uint64_t fractionalBits = 6; // = 6:「ScalingLineP8.va」和「ScalingLineP16.va」中的預設值

uint64_t noOfFractionalLUTs = parallelism == 8 ? 1 : 4; // 小數表格數 = 1(在「ScalingLineP8.va」中)且 = 4(在「ScalingLineP16.va」中)

int InputWidth; // 輸入影像的寬度

int OutputWidth; // 傳送到 PC 的影像寬度

針對 VisualApplets 設計「ScalingLineP16.va」,將 parallelism 參數設為 16,針對「ScalingLineP8.va」則設為 8。 fractionalBits 的數量 6 是 兩個設計中的預設值。設計「ScalingLineP16.va」 具有四個表格 (const int noOfFractionalLUTs = 4),其中包含 用於差值的像素間位置 (請參閱圖 340)。設計「ScalingLineP8.va」則 只有一個表格 (const int noOfFractionalLUTs = 1)。線形影像的 Scaling 是由 InputWidth 與 OutputWidth 之間的關係所定義。

2. 執行程式!

3. 建立下列檔案,這些檔案可載入至 VisualApplets 設計中的查找表:

檔案 VA LUT
FractionalTable_0.txt 至 FractionalTable_3.txt Fractional_Part0 (若 parallelism 為 8 則為 Fractional) 至 FractionalPart_3
PickerTable_0.txt 至 PickerTable_15.txt (或至 PickerTable_7.txt) PickComponent0 至 PickComponent15 (或至 PickComponent7)
TableWordsToRead.txt WordsToRead
RemoveTable.txt RemovePixel

表 25. Visual Applets 中的檔案及其對應的查找表


此外,還會建立文字檔案 ScalingTable.txt。它包含每個輸出影像像素在 來源影像中的對應座標 (另請參閱節 )。

ScalingTableLine.m 與 LUTS_Scaling.m

請開啟模組「ScalingTableLine.m」並定義參數

InputWidth=…;

OutputWidth=…;

1. 執行程式!

2.隨即建立文字檔案 ScalingTableLine.txt。它包含每個輸出影像像素在 來源影像中的對應座標。

3. 請開啟模組「LUTS_Scaling.m」並定義參數

parallelism = ...;

NoOfFractionalBits=...;

NoOfFractionalTables=...;

執行程式!所建立的檔案對應至表 25 中的檔案,可載入至 VisualApplets 設計中的查找表。