(1)对数变换是图像处理中常见的非线性变换方式,用于强调图像的低灰度部分,扩展被压缩在高值图像中的暗像素。
(2)对数变换公式:
其中,r为原始像素点(归一化的小数),C是调整对比度的常数,S是对数变换后的像素点(归一化的小数)。
对数变换的效果是使图像的暗部细节更加清晰,而对于亮部区域,则可能会减少一些细节的层次感。
对数变换在天文图像处理、医学图像处理领域尤为重要,因为这些领域的图像通常包含大量暗区域,通过对数变换可以更好地观察到图像的细节特征。
(3)matlab代码
% 清空工作区
clear all;
close all;
% 设置文件路径 - 使用正斜杠
img_path = 'D:/FPGA/Image_processing/14_log/matlab/1_1920x1080.bmp';
output_path = 'D:/FPGA/Image_processing/14_log/matlab/';
% 读取图像
img = imread(img_path);
% 应用log变换
img_log = log_f1(img,1);
img_log2 = log_f2(img, 2);
% 保存处理后的图片
imwrite(img_log, [output_path 'log_result_c1.png']);
imwrite(img_log2, [output_path 'log_result_c2.png']);
% 生成COE文件
generate_coe_file(output_path, 1.0, 'log_table_c1.coe');
generate_coe_file(output_path, 2.0, 'log_table_c2.coe');
% 显示结果
figure('Name', 'Log Transform Results');
subplot(1,3,1);
imshow(img);
title('Original');
subplot(1,3,2);
imshow(img_log);
title('Log (c=1.0)');
subplot(1,3,3);
imshow(img_log2);
title('Log (c=2.0)');
% 调整图像窗口大小
set(gcf, 'Position', [100, 100, 900, 300]);
% 函数定义部分
function gamma_corrected = log_f1(img, c)
if nargin < 2
c = 1.0;
end
% 转换为double进行计算
img_double = double(img);
gamma_corrected = uint8(255 * c * log(img_double/255 + 1));
gamma_corrected = min(max(gamma_corrected, 0), 255);
end
function gamma_corrected = log_f2(img, c)
if nargin < 2
c = 2.0;
end
% 创建查找表
table = c * log(double(0:255)/255.0 + 1) * 255;
table = min(max(table, 0), 255);
table = uint8(table);
% 使用查找表进行变换
gamma_corrected = intlut(img, table);
end
function generate_coe_file(output_path, c, filename)
% 生成查找表
table = c * log(double(0:255)/255.0 + 1) * 255;
table = min(max(table, 0), 255);
table = uint8(table);
% 创建并打开COE文件
fid = fopen([output_path filename], 'w');
% 写入COE文件头(只保留必要的初始化信息)
fprintf(fid, 'memory_initialization_radix=10;\n');
fprintf(fid, 'memory_initialization_vector=\n');
% 写入数据
for i = 1:255
fprintf(fid, '%d,\n', table(i));
end
% 写入最后一个数据(不带逗号)
fprintf(fid, '%d;\n', table(256));
% 关闭文件
fclose(fid);
fprintf('Generated COE file: %s\n', filename);
end
(4)FPGA实现
module image_log
(
input wire [7:0] red ,
input wire [7:0] green ,
input wire [7:0] blue ,
input wire clk ,
input wire mode , //0表示log1 1表示log2
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;
log2_8x256 log2_8x256_inst_red
(
.clka (clk ),
.addra (red ),
.douta (red_douta )
);
log1_8x256 log1_8x256_inst_red
(
.clka (clk ),
.addra (red ),
.douta (red_doutb )
);
log2_8x256 log2_8x256_inst_green
(
.clka (clk ),
.addra (green ),
.douta (green_douta)
);
log1_8x256 log1_8x256_inst_green
(
.clka (clk ),
.addra (green ),
.douta (green_doutb)
);
log2_8x256 log2_8x256_inst_blue
(
.clka (clk ),
.addra (blue ),
.douta (blue_douta )
);
log1_8x256 log1_8x256_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
- 顶层设置mode=0,实验现象如下:
- 顶层设置mode=1,实验现象如下: