对于图像的灰度处理,原理与基于FPGA的图像反转相同,但算法不同。相交于基于FPGA的图像反转,基于FPGA的图像灰度处理操作时间由于FPGA的并行性,其处理时间与前者相同。虽然工作量大了4倍左右,但处理时间基本相同,在仿真中,仍在5.2ms完成了处理。凸显出FPGA图像处理的优势特点。下文将对FPGA图像灰度处理各部分进行讲解。
- 处理效果
先上处理效果,以下为对我妹妹的脸部进行灰度处理效果。
512*512 处理前
512*512 处理后
- 处理过程
通过python使用PILLOW,获得输入bmp图片的RGB值,并将R/G/B三个分量分别以16进制写入三个txt文件中。再通过vivado仿真FPGA处理,读取三个txt文件数据分别到三个寄存器中。再从寄存器中读取数据,以verilog语言进行RGB转YCbCr格式处理。在格式转换过程中,同时以两个always模块处理乘、加和一个assig取高8位进行运算。得到YCbCr的Y分量之后,将Y分量输出到一个txt文件中,即为灰度转换的512*512图片的结果。通过python使用OpenCV将txt文件读取,分配到512*512个像素中,即可得到灰度处理后的bmp图像。
2.1读取lzy.bmp图像,通过配置miniconda环境中的PILLOW库,读取图片RGB数据,分离输出RGB的值到red、green、blue.txt文件。
from PIL import Image
# 打开图像文件
image = Image.open('lzy.bmp') # 图像文件路径
# 获得图像的 RGB 数据
rgb_values = list(image.getdata())
# 分离 R、G、B 值
r_values = [rgb[0] for rgb in rgb_values]
g_values = [rgb[1] for rgb in rgb_values]
b_values = [rgb[2] for rgb in rgb_values]
# 将 R、G、B 值写入文本文件
with open('red.txt', 'w') as file:
for value in r_values:
file.write(format(value, '02X') + '\n')
with open('green.txt', 'w') as file:
for value in g_values:
file.write(format(value, '02X') + '\n')
with open('blue.txt', 'w') as file:
for value in b_values:
file.write(format(value, '02X') + '\n')
# 关闭图像文件
image.close()
2.2在vivado中用Verilog语言编写RGB转YCbCr源文件、并编写testbench文件读取数据进行仿真。在源文件中,对于YCbCr格式由于在Verilog语言中,对浮点运算处理较为复杂,所以乘100转为整数数据处理,简化运算。通过Y =(77 *R + 150*G + 29 *B)>>8,进行计算,先进行乘法运算,再进行加法运算,最后取高8位,得到应输出的Y值。
Source:
module rgb_to_ycbcr
(
input clock,
input rst,
input [7:0] input_red_data,
input [7:0] input_green_data,
input [7:0] input_blue_data,
output [7:0] output_gray_data
);
reg [15:0] img_red_r0;
reg [15:0] img_green_r0;
reg [15:0] img_blue_r0;
always@(posedge clock or negedge rst)
begin
if(rst)
begin
img_red_r0 <= 0;
img_green_r0 <= 0;
img_blue_r0 <= 0;
end
else
begin
img_red_r0 <= input_red_data * 8'd77;
img_green_r0 <= input_green_data * 8'd150;
img_blue_r0 <= input_blue_data * 8'd29;
end
end
reg [15:0] img_Y_r0;
always@(posedge clock or negedge rst)
begin
if(rst)
begin
img_Y_r0 <= 0;
end
else
begin
img_Y_r0 <= img_red_r0 + img_green_r0 + img_blue_r0;
end
end
assign output_gray_data = img_Y_r0[15:8];
endmodule
在testbench仿真文件中,通过分别读取先前输出的red/green/blue.txt文件到,red/green/blue_data寄存器中,设置基本仿真条件,从寄存器输入数据到input_red/green/blue_data中。创建gray.txt文件,将输出结果output_gray_data输入到gray.txt文件中,即可得到灰度处理后的灰度值。
Simulation:
`timescale 1ns/1ps
module rgb_to_ycbcr_tb;
reg clock;
reg rst;
reg [7:0] red_data [(512*512-1):0];
reg [7:0] green_data [(512*512-1):0];
reg [7:0] blue_data [(512*512-1):0];
reg[18:0] cnt;
integer file_id;
wire[7:0] input_red_data;
wire[7:0] input_green_data;
wire[7:0] input_blue_data;
wire[7:0] output_gray_data;
initial begin
clock = 1'b0;
forever #10 clock = ~clock;
end
initial begin
cnt = 19'b0;
$readmemh("./red.txt", red_data);
$readmemh("./green.txt",green_data);
$readmemh("./blue.txt",blue_data);
file_id = $fopen("./gray.txt", "w");
end
initial begin
rst = 1'b1;
#195 rst = 1'b0;
#20000000 $stop;
$fclose(file_id);
end
assign input_red_data = red_data[cnt[17:0]];
assign input_green_data = green_data[cnt[17:0]];
assign input_blue_data = blue_data[cnt[17:0]];
always @(posedge clock or posedge rst)
if (rst) begin /
cnt <= 19'b0; /
end /
else if(cnt[18] == 1'b0) /
begin /
$fwrite(file_id, "0x%x\n", output_gray_data); /
cnt <= cnt + 1'b1; /
end /
rgb_to_ycbcr u_rgb_to_ycbcr(
.clock(clock),
.rst(rst),
.input_red_data(input_red_data),
.input_green_data(input_green_data),
.input_blue_data(input_green_data),
.output_gray_data(output_gray_data)
);
endmodule
vivado仿真结果如下图:
仿真总图
仿真开始阶段图
仿真中间部分截取图
将在python转换得到的三个txt文件,放在工程文件的xsim文件夹里,仿真的结果都输出在了xsim文件夹里的gray.txt。
blue.txt
red.txt
green.txt
gray.txt
可以看到red/green/blue.txt数据数量均为262136个,输出到gray.txt文件中,数据量也为262136个十六进制数,所有数据都完成了运算,表明仿真成功。
2.3在OpenCV中将输出的txt文件转为bmp图像进行输出。
import cv2
import numpy as np
'''
main entry
'''
def main():
picture = cv2.imread('./lzy.bmp')
for i in range(512):
for j in range(512):
picture[i, j] = 255
f = open("./gray.txt", 'r')
for i in range(512 * 512):
line = f.readline()
picture[int(i / 512), int(i % 512)] = int(line, 16)
f.close()
cv2.imwrite('./new_lzy.bmp', picture)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
至此,可以看到在vivado仿真中,与FPGA图像反转处理进行对比,在处理的数据量增加的情况下,处理时间并没有改变,在图像处理中,我们可以广泛应用FPGA的并行特性,实现硬件加速。在仿真中,以20ns一个周期的虚拟时钟进行仿真,处理速度就可以达到5.26ms,如果在FPGA实机中,以更快的时钟速度运行,并且不需要运行仿真文件,直接读取通过存储器传来的数据,速度将可以获得大更大的提高。
需要工程源码的友友可以在下方评论。文章来源:https://www.toymoban.com/news/detail-763538.html
文章来源地址https://www.toymoban.com/news/detail-763538.html
到了这里,关于基于FPGA的图像灰度处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!