数字图像处理(21):伽马校正

        (1)Gamma校正是一种在图像处理中非常广泛使用的技术,用来调整图像的亮度和对比度,改善图像质量。其原理是基于人眼对亮度感知的非线性特性:人眼对亮度的敏感度随着亮度的增加而减少,也就是说,当亮度较低时,人眼对亮度变化更敏感,如下图所示:

        (2)Gamma校正公式:

                O=C*I^{r}

        其中,C和r都为常数,C为亮度和对比度缩放系数,通常取值为1,r为gamma值,I为归一化的值,范围是0~1,O为输出值。

        由图可以看到:当r小于1时,会拉伸灰度较低的区域,同时会压缩灰度较高的部分,会使图像暗部更亮;当r大于1时,会拉伸灰度较高的区域,同时会压缩灰度交低的部分,会使图像亮度更亮。

  • 如果一张照片暗部细节模糊不清,可以用 r<1 的曲线来处理,使暗部细节更清晰。
  • 如果一张照片高光部分过于平淡,可以用 r>1 的曲线来处理,使高光部分层次更丰富。

        (3)matlab实现代码:

% 读取图像
img = imread('D:\FPGA\Image_processing/13_gamma/matlab/1_1920x1080.bmp');

% 应用gamma校正
img_gamma1 = gamma_f1(img, 2.2);      % gamma=2.2
img_gamma2 = gamma_f1(img, 1/2.2);    % gamma=1/2.2

% 显示结果
figure('Name', 'Gamma Correction Results');

subplot(1,3,1);
imshow(img);
title('Original');

subplot(1,3,2);
imshow(img_gamma1);
title('Gamma = 2.2');  

subplot(1,3,3);
imshow(img_gamma2);
title('Gamma = 1/2.2');

% 方法1: 幂函数
function gamma_corrected = gamma_f1(img, gamma)
    if nargin < 2
        gamma = 2.0;
    end
    % 将图像归一化到0-1范围,进行gamma校正,然后还原到0-255范围
    gamma_corrected = uint8(255 * power(double(img) / 255, gamma));
end

% 方法2: 查表法
function gamma_corrected = gamma_f2(img, gamma)
    if nargin < 2
        gamma = 2.0;
    end
    % 创建查找表
    table = uint8(power((0:255)/255, gamma) * 255);
    % 使用查找表进行映射
    gamma_corrected = intlut(img, table);
end

        (4)生成coe文件代码:

% 清空工作区
clear all;
close all;

% 计算gamma=2.2的查找表
gamma_2_2 = uint8(power((0:255)/255, 2.2) * 255);

% 计算gamma=1/2.2的查找表
gamma_1_2_2 = uint8(power((0:255)/255, 1/2.2) * 255);

% 生成gamma=2.2的COE文件
fid = fopen('gamma_2_2.coe', 'w');
fprintf(fid, 'memory_initialization_radix=10;\n');
fprintf(fid, 'memory_initialization_vector=\n');
for i = 1:255
    fprintf(fid, '%d,\n', gamma_2_2(i));
end
fprintf(fid, '%d;', gamma_2_2(256));
fclose(fid);

% 生成gamma=1/2.2的COE文件
fid = fopen('gamma_1_2_2.coe', 'w');
fprintf(fid, 'memory_initialization_radix=10;\n');
fprintf(fid, 'memory_initialization_vector=\n');
for i = 1:255
    fprintf(fid, '%d,\n', gamma_1_2_2(i));
end
fprintf(fid, '%d;', gamma_1_2_2(256));
fclose(fid);

% 绘制查找表曲线进行对比
figure;
plot(0:255, gamma_2_2, 'b-', 'LineWidth', 2);
hold on;
plot(0:255, gamma_1_2_2, 'r-', 'LineWidth', 2);
plot(0:255, 0:255, 'k--', 'LineWidth', 1);
grid on;
title('Gamma Correction Curves');
xlabel('Input Pixel Value');
ylabel('Output Pixel Value');
legend('gamma = 2.2', 'gamma = 1/2.2', 'Linear');

        coe文件以文本形式打开,如下:

        (5)ROM       IP核的配置

        (6)FPGA实现

module image_gamma
(
    input   wire    [7:0]   red         ,
    input   wire    [7:0]   green       ,
    input   wire    [7:0]   blue        ,
    input   wire            clk         ,
    input   wire            mode        ,     //1表示gamma2.2    0表示gamma1/2.2
    
    output  wire    [7:0]   red_adjust  ,
    output  wire    [7:0]   green_adjust,
    output  wire    [7:0]   blue_adjust       
    
);

wire    [7:0]   red_douta,red_doutb,green_douta,green_doutb,blue_douta,blue_doutb;

gamma_8x256     gamma_8x256_inst_red 
(
    .clka           (clk        ),  
    .addra          (red        ),  
    .douta          (red_douta  )  
);

gamma_8x256_2   gamma_8x256_2_inst_red 
(
    .clka           (clk        ),  
    .addra          (red        ), 
    .douta          (red_doutb  )  
);

gamma_8x256     gamma_8x256_inst_green 
(
    .clka           (clk        ),  
    .addra          (green      ),  
    .douta          (green_douta)  
);

gamma_8x256_2   gamma_8x256_2_inst_green
(
    .clka           (clk        ),  
    .addra          (green      ), 
    .douta          (green_doutb)  
);

gamma_8x256     gamma_8x256_inst_blue 
(
    .clka           (clk        ),  
    .addra          (blue       ),  
    .douta          (blue_douta )  
);

gamma_8x256_2   gamma_8x256_2_inst_blue
(
    .clka           (clk        ),  
    .addra          (blue       ), 
    .douta          (blue_doutb )  
);

assign red_adjust = mode ? red_douta : red_doutb;
assign green_adjust = mode ? green_douta: green_doutb;
assign blue_adjust = mode ? blue_douta : blue_doutb;

endmodule

        (7)实验现象

  • 顶层模块输入mode = 1,实验现象如下:

  • 顶层模块输入mode = 0,实验现象如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值