什么是图像的log变换?
总的来说,对数变换是一种常用的图像增强技术,可以改善图像的视觉质量、减少噪声以及突出图像中的细节,从而提高图像在视觉感知和分析中的效果和可用性。
图像的对数变换(log transformation)是一种用于增强图像对比度的常见方法之一。它通过对图像的像素值取对数来扩展较低亮度的区域,并压缩较高亮度的区域,从而增强图像的细节和对比度。
对数变换的主要特点是可以扩展图像的暗部细节,使得低亮度区域的像素值被映射到较大的范围内,从而提高了图像的对比度。然而,对数变换对于较亮的区域的影响相对较小,可能会导致亮度信息的丢失。
对数变换常用于图像处理中的动态范围压缩、图像增强、去噪等应用中。
为什么要做图像的log变换?
对图像进行对数变换的主要目的有几个:
-
增强对比度:对数变换可以扩展图像的灰度动态范围,将较低灰度值的区域拉伸,同时压缩较高灰度值的区域,从而增强图像的对比度。这对于某些图像来说,特别是那些灰度范围较窄的图像,可以使图像更具视觉效果。
-
压缩动态范围:在一些应用中,图像的动态范围可能过大,包含了大量的细节信息。对数变换可以帮助压缩图像的动态范围,使得图像中的细节更容易被观察和分析。
-
减少噪声:在图像处理中,对数变换也可以用于减少图像中的噪声。由于对数函数的曲线特性,对低灰度值的像素施加更大的变换,因此可以将低灰度值的噪声信号压缩到较小的范围内,从而减少图像中的噪声影响。
-
增强图像细节:对数变换有助于突出图像中的细节和纹理,特别是对于暗部细节。这使得图像在观察和分析时更容易捕捉到细微的变化和特征。
log变换的公式
对于灰度图像,图像的对数变换公式如下:
其中,r 表示原始图像的像素值,s 表示变换后的像素值,c 是一个常数,用于调节变换后的亮度范围。其中 c 为常数系数, r 为像素值范围 0~255。
(生成这个交互式曲线图的python代码在文章的后面有提供)
如图所示, 对数曲线在像素值较低的区域斜率较大, 像素值较高的区域斜率比较低, 所以图像经过对数变换之后, 在较暗的区域对比度将得到提升, 因而能增强图像暗部的细节。
python实现图像的log变换
PotatoPie 4.0 实验教程(22) —— FPGA实现摄像头图像对数(log)变换-Anlogic-安路论坛-FPGA CPLD-ChipDebug
这段代码会读取名为 Lena.jpg 的图片文件,将其转换为灰度图像,并应用 log 变换。然后,它会显示原始图像、灰度图像和经过 log 变换后的图像。
可以看到图像的暗部被明显提升了。
matlab实现实现图像的log变换
PotatoPie 4.0 实验教程(22) —— FPGA实现摄像头图像对数(log)变换-Anlogic-安路论坛-FPGA CPLD-ChipDebug
这段 MATLAB 代码实现了相同的功能,包括读取图像、将图像转换为灰度图像、应用对数变换以及显示原始图像、灰度图像和对数变换后的图像。
FPGA工程解析
工程数据流图
工程层次图
代码解析
与demo18相比,只是多了一个img_log的模块,也就是下面这一段代码,在从SDRAM读出来之后,经它处理后再输出hdmi_tx模块。
img_log u_img_log
(
.i_clk(clk_pixel),
.i_rst_n(sys_rst_n),
.i_hs(VGA_HS),
.i_vs(VGA_VS),
.i_de(VGA_DE),
.i_r(VGA_RGB[23:16]),
.i_g(VGA_RGB[15:8]),
.i_b(VGA_RGB[7:0]),
.o_hs(log_hs),
.o_vs(log_vs),
.o_de(log_de),
.o_r(log_data[23:16]),
.o_g(log_data[15:8]),
.o_b(log_data[7:0])
);
对于FPGA做log运算最好的办法是我们先用matlab或者python把 c*log(0~255)的值计算并输出到文本文件中,然后填入log_rom.v这个文件中即可。下面的代码提供了直接输出log_rom.v的功能,分别提供了pyton版本和matlab版本,代码中c取30。
pyton版本
PotatoPie 4.0 实验教程(22) —— FPGA实现摄像头图像对数(log)变换-Anlogic-安路论坛-FPGA CPLD-ChipDebug
matlab版代码
PotatoPie 4.0 实验教程(22) —— FPGA实现摄像头图像对数(log)变换-Anlogic-安路论坛-FPGA CPLD-ChipDebug
此 MATLAB 代码将执行与Python版代码相同的操作,并生成相同的 COE 文件和图像。
因此FPGA中只需要读出log的值即可,
log_rom u_r
(
.clka (i_clk ),
.addra (i_r ),
.ena (1'b1 ),
.douta (o_r )
);
由于是纯组合逻辑,行场信号都不需要延一拍直接输出即可。
assign o_hs = i_hs;
assign o_vs = i_vs;
assign o_de = i_de;
管脚约束
与PotatoPie 4.0 实验教程(18) —— FPGA实现OV5640摄像头采集以SDRAM作为显存进行HDMI输出显示相同,不作赘述。
时序约束
与PotatoPie 4.0 实验教程(18) —— FPGA实现OV5640摄像头采集以SDRAM作为显存进行HDMI输出显示相同,不作赘述。
实验结果
还是以咱们的小金猪作为主角。