前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于FPGA的灰度图像处理之幂律(伽马)变化

基于FPGA的灰度图像处理之幂律(伽马)变化

作者头像
FPGA开源工作室
发布2019-10-29 10:50:17
1.3K0
发布2019-10-29 10:50:17
举报
文章被收录于专栏:FPGA开源工作室
FPGA开源工作室

FPGA/图像处理/创业/职场

关注

基于FPGA的灰度图像处理之幂律(伽马)变化

1 背景知识

幂律变换的基本形式为:

----------------------------------------------------------------------------------------(1)

其中c和r为正常数。有时考虑到偏移量 可将式(1)写为

------------------------------------------------------------------------------------(2)

偏移量一般是显示标定问题,作为一个结果,通常在式(1)中忽略不计。对于不同的值,s与r的关系如图1所示。

图1 r变换曲线

与对数变换的情况类似,部分r值的幂律曲线将较窄范围的暗色输入值映射为较宽范围的输出值,相反的,对于输入高灰度级值时也成立。然而与对数函数不同的是,随着r值的变化,将简单地得到一簇可能的变化曲线。如图1所示,r>1的值所生成的曲线和r<1的值所生成的曲线的效果完全相反。当c=r=1时简化成了恒等变换。

用于图像获取,打印和显示的各种设备根据幂律来产生响应。习惯上,幂律方程中的指数称为伽马。用于校正这些幂律响应现象的处理称为伽马校正。

图2 航拍图幂律变换

如图2所示,a航拍原图b~d令c=1且分别等于3.0,4.0和5.0时应用式(1)给出的变换的结果(此例的原图像由NASA提供)。

2 FPGA实现

图3 FPGA实现幂律变换框架图

由图2可知对于灰度图像直接经过幂律变换就可以得到幂律变换图像,但是对于FPGA直接实现对数公式显然难度很大。在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

实验结果:

图4 原图

图5原图灰度显示

图6整体变暗

图7整体变亮

结果分析:

图6、图7和图5相比,图6明显变暗,图7明显变亮。此技术可以应用在图像采集系统上,当拍摄的光线较暗时,我们可以采取亮变换;当光线过强时,我们可以采取暗变化,从而达到人眼更适合的效果。

3 基于ov5640的图像采集系统的幂律变换移植

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数据整个图像彩色相比较原RGB图像变暗;通过对R,G,B三个通道进行root处理后合成新的16bitRGB数据整个图像彩色相比较原RGB图像变亮。

有兴趣的同学可以将square数据和sqrt数据线性叠加来输出彩色图像或者与RGB原通道数据进行线性叠加。结果将是下图:

我们可以调整彩色的不同明亮度来达到不同的效果。

请欣赏视频:

视频内容
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FPGA开源工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档