基于FPGA的灰度圖像處理之冪律(伽馬)變化
掃描二維碼
隨時隨地手機看文章
基于FPGA的灰度圖像處理之冪律(伽馬)變化
1 背景知識
冪律變換的基本形式為:
----------------------------------------------------------------------------------------(1)
其中c和r為正常數(shù)。有時考慮到偏移量 可將式(1)寫為
------------------------------------------------------------------------------------(2)
偏移量一般是顯示標定問題,作為一個結(jié)果,通常在式(1)中忽略不計。對于不同的值,s與r的關(guān)系如圖1所示。
圖1 r變換曲線
與對數(shù)變換的情況類似,部分r值的冪律曲線將較窄范圍的暗色輸入值映射為較寬范圍的輸出值,相反的,對于輸入高灰度級值時也成立。然而與對數(shù)函數(shù)不同的是,隨著r值的變化,將簡單地得到一簇可能的變化曲線。如圖1所示,r>1的值所生成的曲線和r<1的值所生成的曲線的效果完全相反。當c=r=1時簡化成了恒等變換。
用于圖像獲取,打印和顯示的各種設備根據(jù)冪律來產(chǎn)生響應。習慣上,冪律方程中的指數(shù)稱為伽馬。用于校正這些冪律響應現(xiàn)象的處理稱為伽馬校正。
圖2 航拍圖冪律變換
如圖2所示,a航拍原圖b~d令c=1且分別等于3.0,4.0和5.0時應用式(1)給出的變換的結(jié)果(此例的原圖像由NASA提供)。
2 FPGA實現(xiàn)
圖3 FPGA實現(xiàn)冪律變換框架圖
由圖2可知對于灰度圖像直接經(jīng)過冪律變換就可以得到冪律變換圖像,但是對于FPGA直接實現(xiàn)對數(shù)公式顯然難度很大。在FPGA中我們采用基于查找表的方式進行冪律變換。
ROM表的制作:
Matlab源碼:
clear all
close all
clc
depth = 256;
width =8;
r = [0:1:255];
x = r; %恒等變換
y =16*sqrt(r);%開根
%z = round(y);
m = (1/256)*r.^2; %r平方
z = round(m);
fid = fopen('E:\matlab_project\log\square.mif','w');%路徑
fprintf(fid,'depth= %d; \n',depth);
fprintf(fid,'width= %d; \n',width);
fprintf(fid,'address_radix=uns;\n');
fprintf(fid,'data_radix = uns;\n');
fprintf(fid,'Content Begin \n');
for(k=1:depth)
fprintf(fid,'%d: %d; \n',k-1,z(k));
end
fprintf(fid,'end;');
hold on
plot(x);
plot(y);
plot(m);
hold off
FPGA源碼:
//------------------------------------------
// power law
//------------------------------------------
wire [7:0] sqrt_data; //root
wire [7:0] square_data;//square
rom_sqrt rom_sqrt_inst(
.address(o_y_8b),
.clken(TFT_de),
.clock(TFT_clk),
.q(sqrt_data)
);
rom_square rom_square_inst(
.address(o_y_8b),
.clken(TFT_de),
.clock(TFT_clk),
.q(square_data)
);
//assign TFT_rgb = {sqrt_data[7:3],sqrt_data[7:2],sqrt_data[7:3]}; //Y
assign TFT_rgb = {square_data[7:3],square_data[7:2],square_data[7:3]}; //Y
//assign TFT_rgb = {o_y_8b[7:3],o_y_8b[7:2],o_y_8b[7:3]}; //Y
實驗結(jié)果:
圖4 原圖
圖5原圖灰度顯示
圖6整體變暗
圖7整體變亮
結(jié)果分析:
圖6、圖7和圖5相比,圖6明顯變暗,圖7明顯變亮。此技術(shù)可以應用在圖像采集系統(tǒng)上,當拍攝的光線較暗時,我們可以采取亮變換;當光線過強時,我們可以采取暗變化,從而達到人眼更適合的效果。
3 基于ov5640的圖像采集系統(tǒng)的冪律變換移植
verilog源碼:
//------------------------------------------
// power law
//------------------------------------------
wire [7:0] sqrt_data; //root
wire [7:0] sqrt_r_data; //root
wire [7:0] sqrt_g_data; //root
wire [7:0] sqrt_b_data; //root
wire [7:0] square_data;//square
wire [7:0] square_r_data;//square
wire [7:0] square_g_data;//square
wire [7:0] square_b_data;//square
rom_sqrt rom_sqrt_r_inst(
.address({rgb[15:11],3'b0}),
.clken(TFT_DE),
.clock(TFT_VCLK),
.q(sqrt_r_data)
);
rom_sqrt rom_sqrt_g_inst(
.address({rgb[10:5],2'b0}),
.clken(TFT_DE),
.clock(TFT_VCLK),
.q(sqrt_g_data)
);
rom_sqrt rom_sqrt_b_inst(
.address({rgb[4:0],3'b0}),
.clken(TFT_DE),
.clock(TFT_VCLK),
.q(sqrt_b_data)
);
rom_square rom_square_r_inst(
.address({rgb[15:11],3'b0}),
.clken(TFT_DE),
.clock(TFT_VCLK),
.q(square_r_data)
);
rom_square rom_square_g_inst(
.address({rgb[10:5],2'b0}),
.clken(TFT_DE),
.clock(TFT_VCLK),
.q(square_g_data)
);
rom_square rom_square_b_inst(
.address({rgb[4:0],3'b0}),
.clken(TFT_DE),
.clock(TFT_VCLK),
.q(square_b_data)
);
assign TFT_RGB = {square_r_data[7:3],square_g_data[7:2],square_b_data[7:3]};
//Y The image darker
//assign TFT_RGB = {sqrt_r_data[7:3],sqrt_g_data[7:2],sqrt_b_data[7:3]};
//Y Image brighter
源碼解釋:
通過對R,G,B三個通道進行square處理后合成新的16bitRGB數(shù)據(jù)整個圖像彩色相比較原RGB圖像變暗;通過對R,G,B三個通道進行root處理后合成新的16bitRGB數(shù)據(jù)整個圖像彩色相比較原RGB圖像變亮。
有興趣的同學可以將square數(shù)據(jù)和sqrt數(shù)據(jù)線性疊加來輸出彩色圖像或者與RGB原通道數(shù)據(jù)進行線性疊加。結(jié)果將是下圖:
我們可以調(diào)整彩色的不同明亮度來達到不同的效果。