• 沒有找到結果。

附錄 C 實作程式碼解說

前置處理:

<API 變數>

設定連續擷取影像的緩衝區為 3 個 IMPLIB_CapImgTbl capimg;

capimg.Num = 3;

設定螢幕顯示需要的參數 IMPLIB_ConfigDispPara para;

para.xsize = 640;

para.ysize = 480;

para.dpx = 0;

para.dpy = 0;

para.disp_plane = IMPLIB_DISP_PLANE_1;

para.overlay_plane = IMPLIB_DISP_PLANE_3;

para.overlay_pallet = IMPLIB_DISP_PALLET_1;

宣告 API 共有 7 張影像可處理,配給對應的記憶體大小,並設定資料型態 int gImgID[7];

gImgID[WORK_Y]= implib_AllocYUVImg( IMPLIB_IMG_FS_640H_512V );

gImgID[LOW_Y] = implib_AllocImg( IMPLIB_IMG_FS_640H_512V );

gImgID[HIGH_Y]= implib_AllocImg( IMPLIB_IMG_FS_640H_512V );

gImgID[HIGH_NEG_Y]=implib_AllocImg( IMPLIB_IMG_FS_640H_512V );

gImgID[IN_YUV]= implib_AllocYUVImg( IMPLIB_IMG_FS_640H_512V );

gImgID[OUT_CYUV]= implib_AllocCYUVImg( IMPLIB_IMG_FS_640H_512V );

<流程控制>

首先初始化影像處理系統,設定即將處理的影像資料型態為 unsigned 8 bit,

設定視窗為(0,0)到(639,479),啟用 video_port0 做為影像輸入 port,讀取影像資料 為 full 640x480,沒有進行 skip 的動作,設定相機接受資料端為 port0 且資料格式 為 YUV,將前述 para 的設定傳進顯示畫面,顯示畫面為彩色影像,設定水平 delay size 為 40,垂直 delay size 為 0,開啟連續擷取影像功能。

程式:

implib_InitIP();

implib_SetIPDataType( IMPLIB_UNSIGN8_DATA );

implib_SetAllWindow(0, 0, IMAGE_WIDTH-1, IMAGE_HEIGHT-1);

implib_ActiveVideoPort( IMPLIB_VIDEO_PORT0 );

implib_SetVideoFrame( IMPLIB_INTERLACE, IMPLIB_VIDEO_FS_640H_480V );

implib_SelectCamera( IMPLIB_CAMERA_PORT0 ,IMPLIB_YUV_CAMERA )

;

implib_SetConfigDisp( &para );

implib_SelectDisp( IMPLIB_YUV_DISPLAY );

implib_SetVFDelay( 40, 0 );

implib_CaptureContinuous(&capimg);

輸入:

<implib_GetCamera API >

類別 型態 名稱 意義

output 參數 int gImgID[IN_YUV]

存放鏡頭擷取的影像的 screen number,資料格式為 YUV422 流程:

將鏡頭擷取到的影像資料存入 gImgID[IN_YUV]中。

程式: screen number

流程:

複製 gImgID[IN_YUV]的影像資料給 gImgID[WORK_Y],使用 gImgID[WORK_Y]的影像進行後續的 TR 演算法。

程式:

implib_IP_Copy(gImgID[IN_YUV], gImgID[WORK_Y]);

< implib_IP_SmoothFLT API >

讀取 gImgID[WORK_Y]的影像資料,與 COEFF 係數進行 converlution,結果 向右位移 6 位元,得到低頻資料給 gImgID[LOW_Y],提供給後續的 TR 演算法進 行計算。

程式:

implib_IP_SmoothFLT(gImgID[WORK_Y], gImgID[LOW_Y], 6, COEFF);

< implib_IP_Sub API >

讀取 gImgID[WORK_Y]的影像資料,減去 gImgID[LOW_Y],得到 gImgID[HIGH_Y],用來保留高頻資料。

程式:

implib_IP_Sub(gImgID[WORK_Y], gImgID[LOW_Y], gImgID[HIGH_Y]);

< implib_IP_Sub API >

反過來讀取 gImgID[LOW _Y]的影像資料,減去 gImgID[WORK _Y],得到 gImgID[HIGH_NEG_Y],用來保留高頻小於 0 的資料。由於資料型態為 unsigned 8,減法時會直接截去超出範圍(0~255)的資料。

程式:

implib_IP_Sub(gImgID[LOW _Y], gImgID[WORK _Y], gImgID[HIGH_NEG_Y]);

< implib_OpenImgDirect API >

類別 型態 名稱 意義

unsigned char* old_dY

直 接 存 取 低 頻 影 像

implib_OpenImgDirect(gImgID[LOW_Y], &xsize, &ysize, &old_dY);

< type transfer >

dY[j] = (float)old_dY[i];

j++;

} }

< implib_CloseImgDirect API >

類別 型態 名稱 意義

input 參數 int gImgID[LOW _Y] 低頻影像

流程:

關閉 gImgID[LOW_Y]的直接存取權限。

程式:

implib_CloseImgDirect(gImgID[LOW_Y]);

TR(tone reproduction)演算法:

Estimate parameter : 計算 Scaling with mid-tone 和 Scaling with white value 模組需 要的 avg、key 和 white 參數。

Scaling with mid-tone : 將影像資料以對數平均 avg 為基準,調整至 key 值。

Scaling with white value : 利用色調重現曲線重新映射影像資料,改善其動態範 圍。

Normalization : 重新正規化影像資料,將範圍調整到 8 位元。

Implib_IP_Histogram:使用 API 統計影像亮度值,並得到最大值與最小值。供給 後續計算 key 和 white。

Jgt_histogram:避免少數極端值影響 key 值,最大值與最小值捨去 1%的像素重新 計算。

Log_average:計算對數域中的平均值。供給後續計算 key。

< Estimate parameter module>

類別 型態 名稱 意義

float * dY 影像亮度

int* gImgID

API 的 screen number,每 個 screen number 即可存取 所對應的影像資料

float scale_constant = 2.0

計算 key 值的 factor,預設

OFeatureTbl feature_tb

存放統計亮度直方圖的資 料結構

流程:

使用 API : implib_IP_Histogram 統計亮度的直方圖,將統計資訊放在

feature_tb 中,其中的 MAX_LEVEL 和 MIN_LEVEL 成員即為最大亮度與最小亮 度,傳這兩個資料給 par 的 dLmax 和 dLmin 成員,再分別查詢 log 表格,得到對 數結果。計算 range 時,若 dLmin 小於 0,則 dLmax 即為 range,否則 range 為 dLmax 減 dLmin。為了避免少數極端值影響平均要對映的數值,使用 jgt_histogram 函數捨去最大亮度與最小亮度的 1%像素,得到新的 dLmax 和 dLmin。另外透過 log_average 函數得到對數域中平均值,再取其指數給 par 結構中的 avg 成員,avg 重新查詢 log 表格得到對數結果給 Lav。計算 below 為 Lav 減 dLmin,above 為 dLmax 減 Lav,power 為 scale_constant 乘上(below-above)與(below+above)的比值,

查詢 key 表格得到 key 值。使用 range 作為 index 查詢 white 表格,得到 white 數 值。將 dLmax 重新取指數,回到線性區域,傳出 par 資料結構提供後續模組計算 使用。

程式:

ret = implib_IP_Histogram(gImgID[HDR_ID], Histogram, &feature_tb, 0);

(par->dLmax) = (feature_tb.MAX_LEVEL);

(par->dLmin) = (feature_tb.MIN_LEVEL);

(par->dLmin) = GET_LOGTABLE(par->dLmin);

(par->dLmax) = GET_LOGTABLE(par->dLmax);

range = (par->dLmax) - (par->dLmin);

if(range < 7.0) range = 7.0;

jgt_histogram(dY, par, Histogram);

(par->avg) = log_average(dY, par);

Lav = GET_LOGTABLE(par->avg);

below = Lav - (par->dLmin);

above = (par->dLmax) - Lav;

power = scale_constant * (below - above) / (below + above);

(par->key) = GET_KEYTABLE(power);

(par->white) = GET_WHITETABLE(range);

(par->dLmax) = GET_EXPTABLE(par->dLmax); // for scale_to_midtone

<implib_IP_Histogram API>

類別 型態 名稱 意義

int gImgID[TR_ID]

要 進 行 統 計 的 影

long* Histogram

存 放 統 計 結 果 的

統計 gImgID[TR_ID]的資料,將直方圖結果存放到 Histogram,並將特徵值存 放於 feature_tb 中。

程式:

implib_IP_Histogram(gImgID[TR_ID], Histogram, &feature_tb, 0);

<jgt_histogram module>

long* Histogram

存 放 統 計 的 直 方

(par->dLmin) = GET_EXPTABLE(par->dLmin);

sum = 0.;

for (i = Color_Depth_sub; i >= 0; i--) {

sum = sum + Histogram[i];

if (sum * 100 > length) {

L99 = i;

break;

} }

sum = 0.;

for (i = 1; i < Color_Depth; i++) {

sum = sum + Histogram[i];

if (sum * 100 > length) {

L1 = i;

break;

} }

(par->dLmin) = GET_LOGTABLE(L1);

(par->dLmax) = GET_LOGTABLE(L99);

<log_average module>

val = GET_LOGTABLE(tempY);

sum += val;

ilength += (float)1.0;

}

}

return GET_EXPTABLE(sum / ilength);

<scaling with mid-tone module>

factor = (par->key) / (par->avg);

for (i = Color_Depth_sub; i >= 0; i --) Ytable[i] = (float)i * factor;

Ytable[256] = par->dLmax * factor;

<scaling with white value module>

Lmax2 = par->white * par->white;

for (i = Color_Depth; i >= 0; i --) {

val = GET_YTABLE(i);

Ytable[i] = val * ((float)1.0 + val / Lmax2) / ((float)1.0 + val );

}

<normalization module>

類別 型態 名稱 意義

input 參數 float * Ytable 影像亮度表格

int* int_Ytable

整 數 影 像 亮 度 表

Ytable[i] = Ytable[i] / Ytable[256] * 256.0;

if(Ytable[i] > 255.0) Ytable[i] = 255.0;

Yratio[i] = Ytable[i] / (float)i;

輸出:

<implib_WriteConvertLUT API>

類別 型態 名稱 意義

input 參數 int* int_Ytable

整 數 影 像 亮 度 表 格

流程:

將 int_Ytable 寫入 API 指定的記憶體位置,可讓 implib_IP_ConverLUT 直接 對位於 API 配置記憶體的影像進行查表。此動作只有每三十個畫面的第一張需要 執行。

程式:

implib_WriteConvertLUT( int_Ytable );

<implib_IP_ConvertLUT API>

類別 型態 名稱 意義

使用 API 對 gImgID[WORK_Y]查詢先前寫入的亮度表格,轉換後的結果即為 新的亮度值。

程式:

implib_IP_ConvertLUT(gImgID[WORK_Y], gImgID[WORK_Y]);

< implib_IP_Add API >

implib_IP_Add(gImgID[WORK _Y], gImgID[HIGH _Y], gImgID[WORK_Y]);

< implib_IP_Sub API >

類別 型態 名稱 意義

int gImgID[WORK_Y] 原始影像 input 參數

int gImgID[HIGH_NEG_Y] 高頻影像負值

output 參數 int gImgID[WORK_Y] 原始影像

流程:

轉換後的原圖再減去高頻影像的負值。

程式:

implib_IP_Sub(gImgID[LOW _Y], gImgID[WORK _Y], gImgID[HIGH_NEG_Y]);

< implib_IP_Copy API >

類別 型態 名稱 意義

input 參數 int gImgID[WORK_Y]

用 來 進 行 TR 處 理 的 screen number

output 參數 int gImgID[IN_YUV]

存放鏡頭擷取的影像的 screen number,資料格式 為 YUV422

流程:

複製 gImgID[WORK_Y]的影像亮度 Y 資料給 gImgID[IN_YUV],同時間,彩 度 UV 也已經更新完成,故 gImgID[IN_YUV]為處理後的彩色影像。

程式:

implib_IP_Copy(gImgID[WORK_Y], gImgID[IN_YUV]);

<implib_CombineYUV API>

類別 型態 名稱 意義

input 參數 int gImgID[IN _YUV] TR 處理後的影像 output 參數 int gImgID[OUT_CYUV]

要 顯 示 在 螢 幕 上

implib_CombineYUV( gImgID[IN_YUV], gImgID[OUT_CYUV] );

<implib_DispImg API>

類別 型態 名稱 意義

input 參數 int gImgID[OUT_CYUV]

要 顯 示 在 螢 幕 上 的彩色影像

流程:

使用 API 讓 gImgID[OUT_CYUV]顯示於螢幕上。

程式:

implib_DispImg( gImgID[OUT_CYUV] );

相關文件