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

相关文章

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q