PotatoPie 4.0 实验教程(25) —— FPGA实现摄像头图像直方图均衡变换

本文主要是介绍PotatoPie 4.0 实验教程(25) —— FPGA实现摄像头图像直方图均衡变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

图像的直方图均衡是什么?

图像的直方图均衡是一种用于增强图像对比度的图像处理技术。在直方图均衡中,图像的像素值被重新分配,以使得图像的直方图变得更均匀,即各个像素值的分布更加平衡。这意味着直方图中每个像素值的频率大致相同,从而使得图像的对比度增强。

直方图均衡可以应用于灰度图像和彩色图像,并且通常用于图像增强、图像预处理以及计算机视觉应用中。它有以下几个主要作用和优势:

  1. 增强对比度:直方图均衡可以增强图像的对比度,使得图像中的细节更加清晰、突出。通过重新分配像素值,可以拉伸直方图,使得图像中的像素值范围更广,从而增加了图像的动态范围。

  2. 消除背景噪声:直方图均衡可以帮助消除图像中的背景噪声,提高图像的质量。通过增强图像的对比度,可以更好地区分目标与背景,减少背景噪声的影响。

  3. 提高图像质量:直方图均衡可以改善图像的视觉质量,使图像更加清晰、生动,提高了图像的观赏性和识别性。

  4. 改善图像分割和特征提取:直方图均衡可以使得图像中不同目标的灰度级别更加明显,有利于图像分割和特征提取。这对于后续的图像分析、目标检测和识别等任务非常重要。

  5. 预处理步骤:直方图均衡通常作为图像预处理的一部分,用于提高后续图像处理算法的性能和准确性。例如,在图像识别、目标跟踪和计算机视觉任务中,对图像进行直方图均衡可以改善算法的鲁棒性和准确率。

总的来说,直方图均衡是一种简单而有效的图像增强技术,可以提高图像的质量和可用性,使得图像在各种应用领域中都能取得更好的效果。

直方图均衡算法的步骤

直方图均衡的步骤通常包括以下几个阶段:

  1. 计算图像的灰度直方图:统计图像中每个灰度级别的像素数量。
  2. 计算累积分布函数(CDF):对灰度直方图进行归一化处理,得到像素值的累积分布函数,该函数描述了每个灰度级别在图像中出现的累积概率。
  3. 根据CDF进行像素值映射:使用累积分布函数对图像的像素值进行重新映射,以使得图像的直方图更加均匀。通常情况下,这涉及到将原始像素值映射到新的像素值,以便在直方图中实现更均匀的分布。
  4. 应用像素值映射:根据映射关系,将图像中的每个像素值替换为对应的新值,从而完成直方图均衡化。

python实现图像的直方图均衡变换源码

PotatoPie 4.0 实验教程(25) —— FPGA实现摄像头图像直方图均衡变换-Anlogic-安路论坛-FPGA CPLD-ChipDebug

这段代码实现了图像的直方图均衡化,并使用 Matplotlib 库在 Python 中进行可视化展示。以下是对代码功能的详细说明:

  1. 导入必要的库

    • os:用于处理文件路径。
    • numpy:用于数组操作和数学计算。
    • cv2:OpenCV 库,用于图像处理。
    • matplotlib.pyplot:用于绘制图像和直方图。
  2. 获取图像路径

    • 使用 os.path.dirname 和 os.path.abspath 函数获取当前 Python 脚本所在目录的路径。
    • 使用 os.path.join 函数构造图像文件的完整路径。
  3. 读取图像

    • 使用 OpenCV 的 cv2.imread 函数读取图像。
  4. 将图像转换为灰度图像

    • 使用 OpenCV 的 cv2.cvtColor 函数将彩色图像转换为灰度图像。
  5. 计算直方图

    • 创建一个长度为 256 的数组 histogram,用于存储灰度级别的像素数量。
    • 使用双重循环遍历图像的每个像素,并在 histogram 中累计每个灰度级别的像素数量。
  6. 计算累积分布函数

    • 创建一个长度为 256 的数组 cumulative_distribution,用于存储每个灰度级别的累积分布函数值。
    • 使用双重循环遍历直方图,计算每个灰度级别的累积像素数量,并将其除以总像素数得到累积分布函数值。
  7. 计算直方图均衡化的灰度值映射表

    • 创建一个长度为 256 的数组 LUT,用于存储直方图均衡化后的灰度值映射表。
    • 将累积分布函数值乘以 255 并四舍五入,得到灰度值映射表。
  8. 直方图均衡化

    • 创建一个与原始图像相同大小的数组 image_equal,用于存储直方图均衡化后的图像。
    • 使用双重循环遍历原始图像的每个像素,根据灰度值映射表将每个像素的灰度值替换为均衡化后的灰度值。
  9. 可视化

    • 使用 Matplotlib 的 plt.imshow 和 plt.bar 函数分别显示原始图像和其直方图。
    • 使用 Matplotlib 的 plt.plot 函数绘制累积分布函数曲线。
    • 使用 Matplotlib 的 plt.show 函数显示图像及其直方图的子图布局。

通过以上步骤,代码实现了直方图均衡化并可视化显示了原始图像、均衡化后的图像、直方图以及累积分布函数。

MATLAB实现图像的直方图均衡变换源码

上面的代码实现了图像的直方图均衡化,具体步骤如下:

  1. 读取图像并转换为灰度图像: 使用imread函数读取名为’dog.png’的图像,并使用rgb2gray函数将彩色图像转换为灰度图像。

  2. 计算直方图: 首先创建一个256×1的零矩阵histogram,用于存储灰度级别的直方图。然后使用嵌套的循环遍历图像的每个像素点,将每个灰度级别出现的频数累加到相应的直方图位置上。

  3. 计算累积分布函数: 创建一个256×1的零矩阵cumulative_distribution,用于存储累积分布函数的值。然后通过循环计算累积分布函数的值,其中使用变量sum累积直方图的频数,并将其除以图像的总像素数(行数乘以列数)得到归一化后的累积分布函数。

  4. 计算灰度值映射表: 创建一个256×1的零矩阵LUT,用于存储直方图均衡化后的灰度值映射表。然后通过循环遍历累积分布函数,对每个灰度级别的累积分布函数值乘以255并四舍五入,得到灰度值映射表。

  5. 直方图均衡化: 创建一个与原始图像大小相同的零矩阵image_equal,用于存储直方图均衡化后的图像。然后通过嵌套的循环遍历原始图像的每个像素点,根据灰度值映射表将每个像素点的灰度值替换为对应的直方图均衡化后的灰度值。

  6. 显示结果: 使用subplot函数将原始图像、直方图、直方图均衡化后的图像以及其直方图和累积分布图显示在一个图像窗口中。标题使用中文显示,并指定使用微软雅黑字体。

工程分析

链接直达

https://item.taobao.com/item.htm?ft=t&id=776516984361

工程层次图

demo18相比,只是多了一个img_histogram的模块,也就是下面这一段代码,在从SDRAM读出来之后,经它处理后再输出hdmi_tx模块。

img_histogram u_img_histogram
(.i_clk          (clk_pixel                ),.i_rst_n        (sys_rst_n                ),.i_hs           (VGA_HS                   ),.i_vs           (VGA_VS                   ),.i_de           (VGA_DE                   ),.i_x_pos        (lcd_xpos                 ),.i_y_pos        (lcd_ypos                 ),.o_hs           (histogram_hs             ),.o_vs           (histogram_vs             ),.o_de           (histogram_de             ),.o_r            (histogram_r              ),.o_g            (histogram_g              ),.o_b            (histogram_b              ) 
);

img_histogram直方图均衡模块源代码分析

从层次图可到这个模块包含两个子ROM模块, 上面这个img_histogram ROM是我们要做直方图均衡的图像数据,dog.png就存在这里,为什么这个实验没有直接对摄像头进行处理,因为直方图需要大量的RAM,而EG4的RAM没有这么大,所以我们用ROM存一个小图来验证这个算法。

下面那个u_img_equal_ram_dp 是用来存储直方图映射表。

接下来我们讲述直方图均衡化的FPGA算法关键点:

1. 从ROM读取dog.png的图像数据

由于我们需要在指定位置处理像,而我们显示屏大于图像的尺寸,因此需要行场计数到达指定位置时才从ROM读取图像数据。

我们用这几个参数定义显示处理图像的位置

parameter H_ACTIVE = 160; //显示区域宽度
parameter V_ACTIVE = 120; //显示区域高度
parameter BEGIN_X = 640; //显示起始坐标
parameter BEGIN_Y = 360; //显示起始坐标

然后分别进行/显示区域行计数和列计数,

if(h_cnt == H_ACTIVE - 1'b1)h_cnt <= 11'd0;else h_cnt <= h_cnt + 11'd1;..... 省略if(v_cnt == V_ACTIVE - 1'b1)v_cnt <= 11'd0;else v_cnt <= v_cnt + 11'd1;

往下看就看到代码定义ROM的地方了

 

//存储dog.png图片数据的ROM

dog_160x120 u_image_buffer(

.doa ({r_d0,g_d0,b_d0}),

.addra (rd_addr ),

.clka (i_clk )

);

接下来的这行代码处理了图像数据ROM的地址计数。

rd_addr <= v_cnt * H_ACTIVE + h_cnt;

2.图像的灰度化

PotatoPie 4.0 实验教程(25) —— FPGA实现摄像头图像直方图均衡变换-Anlogic-安路论坛-FPGA CPLD-ChipDebug

3.计算直方图

跟matlab和python代码一样,统计一帧图像数据中每个灰度出现的次数

hist_ram[gray_d0[15:8]]<=hist_ram[gray_d0[15:8]]+1'b1;

4.计算累积分布函数建立映射表

PotatoPie 4.0 实验教程(25) —— FPGA实现摄像头图像直方图均衡变换-Anlogic-安路论坛-FPGA CPLD-ChipDebug

5. 将计算结果写映射表的ROM

例化双端RAM用于存储映射表

// 存储直方图均衡化后的灰度值映射表,输出时直接用灰度值作为地址进行查表
ram_dp#(.DATA_WIDTH   (8          ),.ADDRESS_WIDTH  (8             )
) u_img_equal_ram_dp(.i_clk      (i_clk        ),.i_data_a    (image_equal    ),.i_addr_a    (wr_addr_cnt    ),.i_wea      (sum_hist_flag_d3  ),.o_qout_a    (          ),.i_data_b    (          ),.i_addr_b    (gray_d0[15:8]    ),.i_web      (          ),.o_qout_b    (hist_out      )
);

显示的时候,直接用灰度值作为地址进行查表读出值即可。

管脚约束

与PotatoPie 4.0 实验教程(18) —— FPGA实现OV5640摄像头采集以SDRAM作为显存进行HDMI输出显示相同,不作赘述。

时序约束

与PotatoPie 4.0 实验教程(18) —— FPGA实现OV5640摄像头采集以SDRAM作为显存进行HDMI输出显示相同,不作赘述。

实验结果

这篇关于PotatoPie 4.0 实验教程(25) —— FPGA实现摄像头图像直方图均衡变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/955882

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

NFS实现多服务器文件的共享的方法步骤

《NFS实现多服务器文件的共享的方法步骤》NFS允许网络中的计算机之间共享资源,客户端可以透明地读写远端NFS服务器上的文件,本文就来介绍一下NFS实现多服务器文件的共享的方法步骤,感兴趣的可以了解一... 目录一、简介二、部署1、准备1、服务端和客户端:安装nfs-utils2、服务端:创建共享目录3、服

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭