当前位置: 首页 > news >正文

FPGA与Matlab图像处理之伽马校正

文章目录

  • 一、什么是伽马校正?
  • 二、伽马校正的由来
  • 三、Matlab实现伽马校正
    • 3.1 matlab代码
    • 3.2 matlab结果
  • 四、Verilog实现伽马校正
    • 4.1 生成初始化ROM文件
    • 4.2 Verilog代码
    • 4.3 仿真结果


一、什么是伽马校正?

  Gamma校正是图像处理中用以调整图像的亮度和对比度来改善图像质量的。Gamma校正是基于人眼对亮度的感知非线性,人眼对亮度的敏感度随着亮度的增加而减少,也就是人眼在图像亮度较低时,人眼对亮度的变换更敏感。例如:人眼在夜晚很容易看见萤火虫,而在白天不容易看到天空中飞翔的鸟。伽马曲线如下所示:

在这里插入图片描述

二、伽马校正的由来

  早期的显示设备(如CRT显示器)在处理光信号时表现出非线性特性。CRT显示器的亮度输出与输入信号的电压之间存在幂律关系:
O = I Y O=I^{Y} O=IY

  Y就是所说的伽马值,例如:给 CRT 显示器输入一个 0.5(I=0.5), CRT 显示器的输出O输出 0.218,输入与输出间存在一个指数大概为 2.2 的幂次关系(这是人们根据实践总结出来的值)。
  不同的Y对于的曲线不一样:

在这里插入图片描述

  • 当伽马值小于1时,会拉伸图像中灰度较低的区域,同时压缩图像中灰度较高的区域,使得图像的暗部变亮,亮度变暗。
  • 当伽马值大于1时,会拉伸图像中灰度较高的区域,同时压缩图像中灰度较低的区域,使得图像的暗部变暗,亮度变亮。

三、Matlab实现伽马校正

  伽马校正就涉及到幂函数运算,直接使用运算就可以了:

3.1 matlab代码

clear all; close all; clc;
% 读取图像
img = imread('...\....\....\....\......\....\.....\dark.bmp'); 
grayImg = rgb2gray(img); % 转换为灰度图像% 选择伽马值
gamma1 = 2.2; % 例如,使用伽马值2.2
gamma2 = 0.5; % 例如,使用伽马值0.5
% 归一化像素值
normalizedImg = double(grayImg) / 255;% 应用伽马校正
correctedImg1 = normalizedImg .^ gamma1;
correctedImg2 = normalizedImg .^ gamma2;% 反归一化像素值
correctedImg1 = uint8(correctedImg1 * 255);
correctedImg2 = uint8(correctedImg2 * 255);% 显示原始和校正后的图像
figure;
subplot(1, 3, 1);
imshow(grayImg);
title('原始图像');subplot(1, 3, 2);
imshow(correctedImg1);
title('伽马2.2校正后的图像');subplot(1, 3, 3);
imshow(correctedImg2);
title('伽马0.5校正后的图像');

3.2 matlab结果

在这里插入图片描述
  可以看到,伽马值2.2使得图像画面亮度部分更亮,暗部部分更暗了,伽马值为0.5使得图像画面亮度部分变暗,暗部部分变亮了。我们不显示灰度图像,直接显示彩色图片:

在这里插入图片描述
  这样也非常的明显看到伽马值对图像亮部暗部的变化。

四、Verilog实现伽马校正

4.1 生成初始化ROM文件

  我们从公式可以看到伽马校正涉及到的是幂函数,但是fpga不擅长处理幂函数,因此我们可以使用一个rom来提前存放好0-255灰阶的幂函数,这样我们输入一个灰度值作为rom的读地址,就能直接得到新的灰度值,ROM的初始文件用Matlab生成,代码如下:

 clear all; close all; clc;
% 设定伽马值
gammaValue = 2.2; % 替换为你想要的伽马值% 生成伽马校正表
LUT = zeros(256, 1);
for i = 0:255LUT(i + 1) = round((i / 255) ^ gammaValue * 255);
end% 生成MIF文件
mifFileName = 'gamma_correction.mif'; % MIF文件名
fileID = fopen(mifFileName, 'w');% 写入MIF文件头
fprintf(fileID, 'DEPTH = 256;\n');
fprintf(fileID, 'WIDTH = 8;\n');
fprintf(fileID, 'ADDRESS_RADIX = HEX;\n');
fprintf(fileID, 'DATA_RADIX = HEX;\n');
fprintf(fileID, 'CONTENT BEGIN\n');% 写入LUT数据
for i = 0:255fprintf(fileID, '%02X : %02X;\n', i, LUT(i + 1));
endfprintf(fileID, 'END;\n');% 关闭文件
fclose(fileID);

  生成的coe文件如下:
在这里插入图片描述

4.2 Verilog代码

  代码很简单,就例化一个256深度,8位宽的ROM,然后把COE文件烧录进去,输入的灰度图像数据作为ROM的读地址,其他的信号都打一拍输出即可,代码如下:

`timescale 1ns / 1psmodule gamma_map(input                                               clk             ,input                                               rst             ,input                                               i_hsync         ,input                                               i_vsync         ,input                                               i_data_valid    ,input           [23:0]                              i_data          , output                                              o_hsync         ,output                                              o_vsync         ,output                                              o_data_valid    ,output          [23:0]                              o_data  
);/***************reg*******************/
reg         ro_hsync     ;
reg         ro_vsync     ;  
reg         ro_data_valid;  
/***************wire******************/
wire  [7:0] rom_data    ;
/***************component*************/
gammp_map_rom u0_gamma_rom (.clka (clk            ),    // input wire clka.addra(i_data[23:16]  ),  // input wire [7 : 0] addra.douta(rom_data       )  // output wire [7 : 0] douta
);
/***************assign****************/
assign o_hsync      = ro_hsync              ;
assign o_vsync      = ro_vsync              ;
assign o_data_valid = ro_data_valid         ;
assign o_data       = {rom_data,rom_data,rom_data}    ;/***************always****************/
always @(posedge clk) beginif(rst == 1'b1)ro_data_valid <= 'd0;else if(i_data_valid == 1'b1)ro_data_valid <= i_data_valid;elsero_data_valid <= 'd0;
endalways @(posedge clk) beginif(rst == 1'b1)ro_hsync <= 1'b0;else ro_hsync <= i_hsync;
endalways @(posedge clk) beginif(rst == 1'b1)ro_vsync <= 1'b0;else ro_vsync <= i_vsync;
endendmodule

4.3 仿真结果

  仿真输入一个彩色图像,然后生成灰度图像以及伽马矫正后的图像命名为new_img:

rgb2gray u_rgb2gray(.clk           ( clk                ),.rst           ( reset              ),.i_data_valid  ( valid_i            ),.i_hsync       ( img_hs             ), .i_vsync       ( img_vs             ), .i_data_r      ( img_data_i[23:16]  ),.i_data_g      ( img_data_i[15:8]   ),.i_data_b      ( img_data_i[7:0]    ),.o_data_valid  ( valid_o            ),.o_hsync       ( o_img_hs           ), .o_vsync       ( o_img_vs           ), .o_data_r      ( img_data_o[23:16]  ),.o_data_g      ( img_data_o[15:8]   ),.o_data_b      ( img_data_o[7:0]    )
);gamma_map u_gamma_map(.clk           ( clk           ),.rst           ( reset         ),.i_hsync       ( o_img_hs      ),.i_vsync       ( o_img_vs      ),.i_data_valid  ( valid_o       ),.i_data        ( img_data_o    ),.o_hsync       (               ),.o_vsync       (               ),.o_data_valid  ( o_post_cal_gray_data_valid  ),.o_data        ( o_post_cal_gray_data        )
);

在这里插入图片描述
在这里插入图片描述
  可以看到gamma值2.2矫正后的图像,亮部区域更亮,暗部区域更暗,和matlab的一致。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • RusTitW:大规模语言视觉文本识别数据集(猫脸码客 第190期)
  • CAD图纸加密软件哪个好?10款2024主流CAD图纸加密软件分享!
  • 监控易监测对象及指标之:全面监控FTP服务器
  • ubuntu服务器版NVIDIA驱动失效解决方案
  • 宝塔Linux部署 Vue + Spring Boot + MySQL + Redis
  • C++中一般指针,指针数组,数组指针
  • Java入门,初识Java
  • web基础—dvwa靶场(五)File Upload
  • 【CMake】使用CMake在VIsual Studio内构建多文件夹工程
  • JavaScript 事件处理
  • Redis——常用数据类型string
  • python 使用seleniumwire获取响应数据以及请求参数
  • Android前台服务如何在后台启动activity?
  • Linux memcg lru lock提升锁性能
  • 架构与业务的一致性应用:实现企业战略目标和合规管理的全面指南
  • 自己简单写的 事件订阅机制
  • Angular 响应式表单之下拉框
  • iOS小技巧之UIImagePickerController实现头像选择
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • oldjun 检测网站的经验
  • PAT A1017 优先队列
  • PHP CLI应用的调试原理
  • php中curl和soap方式请求服务超时问题
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • V4L2视频输入框架概述
  • 高性能JavaScript阅读简记(三)
  • 近期前端发展计划
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 使用 @font-face
  • 一份游戏开发学习路线
  • 译有关态射的一切
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (二)linux使用docker容器运行mysql
  • (转)Sublime Text3配置Lua运行环境
  • .JPG图片,各种压缩率下的文件尺寸
  • .net core 依赖注入的基本用发
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .net 获取url的方法
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .Net 中Partitioner static与dynamic的性能对比
  • @EnableConfigurationProperties注解使用
  • @property括号内属性讲解
  • @vue-office/excel 解决移动端预览excel文件触发软键盘
  • [ Socket学习 ] 第一章:网络基础知识
  • []常用AT命令解释()
  • [Angular] 笔记 18:Angular Router
  • [AX]AX2012 AIF(四):文档服务应用实例
  • [BT]BUUCTF刷题第4天(3.22)
  • [BZOJ1040][P2607][ZJOI2008]骑士[树形DP+基环树]
  • [C/C++]数据结构 堆的详解
  • [C进阶] 数据在内存中的存储——浮点型篇
  • [FFmpeg] windows下安装带gpu加速的ffmpeg