前置處理:
<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( ¶ );
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] );