Matlab+FPGA进行灰度图像处理

这篇具有很好参考价值的文章主要介绍了Matlab+FPGA进行灰度图像处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

…# Matlab+FPGA进行灰度图像处理(两种方式)Matlab+FPGA进行灰度图像处理

*MATLAB主要用于思路验证,转到FPGA的话需要对底层函数逻辑清楚才行,python也能进行matlab在这里做的所有操作,有兴趣可以深入。

1.matlab读取图片显示:

pic_rgb = imread('1.jpg'); %477x692x3
figure; imshow(pic_rgb);

//调用函数灰度显示
pic_gray = rgb2gray(pic_rgb);%477x692
figure; imshow(pic_gray);

2.matlab灰度反显

pic_reverse_gray = pic_gray;  %确定图片大小

for i = 1:477
	for j = 1:692
		pic_reverse_gray(i,j) =uint8(255-pic_gray(i,j));
	end
end
figure; imshow(pic_reverse_gray);

3.matlab二值化,将灰度进行黑白划分

pic_2 = pic_gray;  %确定图片大小

for i = 1:477
	for j = 1:692
			if (pic_gray(i,j)>140)    %140为分界线,可自由设置
				pic_2(i,j) = uint8(255);
			else
				pic_2(i,j) = uint8(0);
			end
	end
end
figure; imshow(pic_2 );

Part1.思路:用matlab将图片写成TXT发送给FPGA进行处理,然后将FPGA处理完的数据返回给matlab进行显示查看是否正确。

  1. matlab把图片转到txt格式,文件名:rgb_data.txt
clear;
clc;
pic_rgb =imread('1.jpg')

pic_txt = fopen('rgb_data.txt','w');

for i = 1:477
	for j = 1:692
		fprintf(pic_txt,'%x \n', pic_rgb (i,j,1));
		fprintf(pic_txt,'%x \n', pic_rgb (i,j,2));
		fprintf(pic_txt,'%x \n', pic_rgb (i,j,3));
	end
end

fclose(pic_txt);
  1. FPGA进行读取txt并进行处理数据,注意小数的变化,并进行仿真处理输出txt格式
module pic_deal(
input	  wire [7:0] rgb_r,
input		wire [7:0] rgb_g,
input		wire [7:0] rgb_b,

output	wire [7:0] gray

);
wire [17:0] gray_temp;
//gray = 0.299*R+0.587*G+0.114*B,扩大1024倍,而后截取整数位
assign gray_temp= 306*rgb_r+601*rgb_g+117*rgb_b;
assign gray     = gray_temp[17:10];
/*考虑四舍五入的话就执行下列方式
assign gray     = (gray_temp[9]==1)?(gray_temp[17:10]+1):gray_temp[17:10];
*/
endmodule
`timescale 1ns/1ps
module rgb_data_tb();
	reg  [7:0] rgb_r;
	reg  [7:0] rgb_g;
	reg  [7:0] rgb_b;
	wire [7:0] gray;

	reg [7:0] rgb_data_mem[990251 : 0];//有多少个数值就改成多少位宽
	reg [19:0] addr;
	integer     fid;
pic_deal rgb2gray_inst(
	.rgb_r(rgb_r),
	.rgb_g(rgb_g),
	.rgb_b(rgb_b),
	.gray (gray)
);
//读取txt的文件内容并存放到寄存器,txt文件在Vivado中要放到xsim文件中,才可以调用
initial $readmemh("rgb_data.txt",rgb_data_mem);
//保存处理的文件
initial fid =$fopen("gray_data.txt");

initial begin
	addr = 0;
	repeat(477*692)begin
		rgb_r = rgb_data_mem[0+addr];
		rgb_g = rgb_data_mem[1+addr];
		rgb_b = rgb_data_mem[2+addr];
		#20;
		$fdisplay(fid,"%d",gray);
		addr = addr +3;
		$fclose(fid);
	end
end
endmodule

注意,在Vivado中生成txt文件的时候,仿真时间的设置对应了数据能否全部记录到生成的文件中,所以需要根据自己的图片大小设置时间长度!具体的方式就是先仿真一次看地址到达最后一个数据值时的时间是多少,再把这个时间改到下面的仿真时间里就好了。结束过后,要刷新一次存放生成文件的文件夹,txt文件才会刷新。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2EFlFYOs-1663839921041)(Matlab+FPGA%E8%BF%9B%E8%A1%8C%E7%81%B0%E5%BA%A6%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%2074d60b363556488a8f301b93f256fb7b/Untitled.png)]

  1. matlab读取txt文件
fid = fopen('gray_data.txt','r');
gray_data = fscanf(fid,'%d');%1维数据,需要转换为二维,转换的方式需要思考一下
	end
fclose(fid);

for i = 1:477
	for j = 1:692
		pic_gray_my(i,j) = uint8(gray_data((i-1)*692+j));%一定要转化格式为无符号8位
end

figure('name','pic_gray_my');
imshow(pic_gray_my);

Part2.思路:通过Matlab将图片写成24位RGB数据txt文本到FPGA中读取,处理并显示,需要有HDMI模块。(进阶,基于彩条显示实验)

准备工程:彩条的显示实验(U1,U2是后续我们自己设计的):

Matlab+FPGA进行灰度图像处理

第一步:生成COE文件给Vivado读取成ROM(注意是24位的)

src = imread('02.jpg');
r = src(:,:,1);
g = src(:,:,2);
b = src(:,:,3);
data_r = reshape(r', 1,46870);
data_g = reshape(g', 1,46870);
data_b = reshape(b', 1,46870);%注意是先处理x 就是行!!!
fid=fopen('rgb_init.coe', 'wt');%打开文件
fprintf(fid, 'MEMORY_INITIALIZATION_RADIX=16;\n');
fprintf(fid, 'MEMORY_INITIALIZATION_VECTOR=\n');
for i = 1 : 46870-1
    fprintf(fid, '%x%x%x,\n', data_r(i),data_g(i),data_b(i));%使用%x表示十六进制数
end
fprintf(fid, '%x%x%x;',data_r(46870), data_g(46870),data_b(46870));%%输出结尾,每个数据后面用逗号或者空格或者换行符隔开,最后一个数据后面加分号
  • 我这里图片大小为218X215=46870,根据不同图片进行调整即可;
  • 得到COE文件如下:
MEMORY_INITIALIZATION_RADIX=16;
MEMORY_INITIALIZATION_VECTOR=
d5cdca,
e2dad7,
fff6f5,
fef4f3,
fef4f3,
...
...
fe324d,
ff3250,
ff3250;

Matlab+FPGA进行灰度图像处理

随后选择Block ROM,这里选BLOCK ROM是因为选用Distribute ROM则会占用很多资源,综合都会慢,尽管用分布式rom不会有始终延迟,但是会很慢!!!所以强烈建议用块式ROM,但是会有两个时钟延迟,后续影响极大,所以要仔细观察,具体设置如下,深度一定要是16的整数倍:
Matlab+FPGA进行灰度图像处理
Matlab+FPGA进行灰度图像处理
Matlab+FPGA进行灰度图像处理

//delay 1 clk
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		begin
			hs_reg_d0 <= 1'b0;
			hs_reg_d1 <= 1'b0;
			hs_reg_d2 <= 1'b0;
			vs_reg_d0 <= 1'b0;
			vs_reg_d1 <= 1'b0;
			vs_reg_d2 <= 1'b0;
			video_active_d0 <= 1'b0; //因为ROM有两个始终延迟所以这里也需要延迟两个CLK
			video_active_d1 <= video_active_d0; 
			video_active_d2 <= video_active_d1; 
		end
	else
		begin
			hs_reg_d0 <= hs_reg;
			hs_reg_d1 <= hs_reg_d0;
			hs_reg_d2 <= hs_reg_d1;
			vs_reg_d0 <= vs_reg;
			vs_reg_d1 <= vs_reg_d0;
			vs_reg_d2 <= vs_reg_d1;
			video_active_d0 <= video_active;
			video_active_d1 <= video_active_d0; 
			video_active_d2 <= video_active_d1; 
		end
end
parameter OSD_WIDTH   =  12'd218;	//设置OSD的宽度,根据图片设置
parameter OSD_HEGIHT  =  12'd215;	//设置OSD的高度,根据图片设置
//horizontal counter in total
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		h_cnt <= 12'd0;
	else if(h_cnt == H_TOTAL - 1)//horizontal counter maximum value
		h_cnt <= 12'd0;
	else
		h_cnt <= h_cnt + 12'd1;
end
//
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		active_x <= 12'd0;
	else if(h_cnt >= H_FP + H_SYNC + H_BP - 1)//horizontal video active
		active_x <= h_cnt - (H_FP[11:0] + H_SYNC[11:0] + H_BP[11:0] - 12'd1);
	else
		active_x <= active_x;
end
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		active_y <= 12'd0;
	else if(v_cnt >= V_FP + V_SYNC + V_BP - 1)//horizontal video active
		active_y <= v_cnt - (V_FP[11:0] + V_SYNC[11:0] + V_BP[11:0] - 12'd1);
	else
		active_y <= active_y;
end
//vertical counter in total
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		v_cnt <= 12'd0;
	else if(h_cnt == H_FP  - 1)//horizontal sync time
		if(v_cnt == V_TOTAL - 1)//vertical counter maximum value
			v_cnt <= 12'd0;
		else
			v_cnt <= v_cnt + 12'd1;
	else
		v_cnt <= v_cnt;
end
//delay the Sync for 1 clk, it is the same meaning
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		hs_reg <= 1'b0;
	else if(h_cnt == H_FP - 1)//horizontal sync begin
		hs_reg <= HS_POL;
	else if(h_cnt == H_FP + H_SYNC - 1)//horizontal sync end
		hs_reg <= ~hs_reg;
	else
		hs_reg <= hs_reg;
end

always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		h_active <= 1'b0;
	else if(h_cnt == H_FP + H_SYNC + H_BP - 1)//horizontal active begin
		h_active <= 1'b1;
	else if(h_cnt == H_TOTAL - 1)//horizontal active end
		h_active <= 1'b0;
	else
		h_active <= h_active;
end
//delay the vertical sync for 1 clk
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		vs_reg <= 1'd0;
	else if((v_cnt == V_FP - 1) && (h_cnt == H_FP - 1))//vertical sync begin
		vs_reg <= HS_POL;
	else if((v_cnt == V_FP + V_SYNC - 1) && (h_cnt == H_FP - 1))//vertical sync end
		vs_reg <= ~vs_reg;  
	else
		vs_reg <= vs_reg;
end

always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		v_active <= 1'd0;
	else if((v_cnt == V_FP + V_SYNC + V_BP - 1) && (h_cnt == H_FP - 1))//vertical active begin
		v_active <= 1'b1;
	else if((v_cnt == V_TOTAL - 1) && (h_cnt == H_FP - 1)) //vertical active end
		v_active <= 1'b0;   
	else
		v_active <= v_active;
end
//*******************************USER_DESIGN***************************//
reg         [19:0] addr,addr0;
reg         [2:0]   cnt;
wire        [23:0] dout,dout0;//rom out 
reg pos_vs_d0,pos_vs_d1;
always @(posedge clk)
begin
    pos_vs_d0 <= vs_reg_d0;
    pos_vs_d1 <= pos_vs_d0;
    region_active_d0 <= region_active;
    region_active_d1 <= region_active_d0;
    region_ACT_d0<=region_ACT;
    region_ACT_d1<=region_ACT_d0;
end
reg region_active,region_active_d0,region_active_d1;
reg region_ACT,region_ACT_d0,region_ACT_d1;
//Region of gray,这里是确定画面上图片的位置,确定X,Y坐标区域范围(灰度图片位置)
always@(posedge clk)
begin
	if(active_y >= 12'd9+ OSD_HEGIHT - 12'd1 && active_y <= 12'd9 + OSD_HEGIHT*2 - 12'd1 && 
active_x >= 12'd9 && active_x  <= 12'd9 + OSD_WIDTH - 12'd1)
		region_ACT <= 1'b1;
	else
		region_ACT <= 1'b0;
end
//region of original pic这里是确定画面上图片的位置,确定X,Y坐标区域范围(原始图片位置)
always@(posedge clk)
begin
	if(active_y >= 12'd9 && active_y <= 12'd9 + OSD_HEGIHT - 12'd1 && active_x >= 12'd9 && 
active_x  <= 12'd9 + OSD_WIDTH - 12'd1)
		region_active <= 1'b1;
	else
		region_active <= 1'b0;
end
//有两个CLK得输出延迟,例化两个图片,这里要分开因为地址不共用,不然会出现错乱
blk_mem_gen_0 U1(
    	.clka                       (clk                    ),   
        .ena                        (region_active          ),
        .addra                      (addr                   ),
        .douta                      (dout                   )  
);
blk_mem_gen_0 U2(
    	.clka                       (clk                    ),   
        .ena                        (region_ACT             ),
        .addra                      (addr0                   ),
        .douta                      (dout0                   )  
);
//RGB2GRAY algorisim,扩大了1024倍,即左移了10位,所以后面只取高8位即可
wire [17:0] line_data;
assign line_data= 306*dout0[23:16]+601*dout0[15:8]+117*dout0[7:0];

always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
	   addr <= 0;
    else if (pos_vs_d0 == 1'b0 && pos_vs_d1 == 1'b1) // each frame resets onece
	   addr <= 0;
	else if (region_active)
	   addr    <= addr +1;
end
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
	   addr0 <= 0;
    else if (pos_vs_d0 == 1'b0 && pos_vs_d1 == 1'b1)
	   addr0 <= 0;
	else if (region_ACT)
	   addr0    <= addr0 +1;
end
always@(posedge clk or posedge rst)
begin
    if(rst == 1'b1)
        begin
            rgb_r_reg <= 8'hFF;
            rgb_g_reg <= 8'h00;
            rgb_b_reg <= 8'h00;
         end
    else if(region_active_d1)begin   //原始图片显示
            rgb_r_reg <= dout[23:16]; //[7:0]
            rgb_g_reg <= dout[15:8];//[15:8]
            rgb_b_reg <= dout[7:0];//
           end
    else if(region_ACT_d1)begin    //灰度图片显示
            rgb_r_reg <= line_data[17:10]; //[7:0]
            rgb_g_reg <= line_data[17:10];//[15:8]
            rgb_b_reg <= line_data[17:10];//
           end
    else begin
            rgb_r_reg <= 8'h00;
            rgb_g_reg <= 8'h00;
            rgb_b_reg <= 8'hff;
           end
 end

Matlab+FPGA进行灰度图像处理

代码的设计一定要根据时序来理解,例如水平计数是从FT+SYNC+BP+activeX/Y计数,有效部分为最后那一部分的activeX/Y,所以像素点的计数才从那里开始。
Matlab+FPGA进行灰度图像处理

最后结果展示:
Matlab+FPGA进行灰度图像处理文章来源地址https://www.toymoban.com/news/detail-480767.html

到了这里,关于Matlab+FPGA进行灰度图像处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Matlab图像处理-灰度插值法

    最近邻法 最近邻法是一种最简单的插值算法,输出像素的值为输入图像中与其最邻近的采样点的像素值。是将 ( u 0 , v 0 ) (u_0,v_0) 点最近的整数坐标 u , v (u,v) 点的灰度值取为 ( u 0 , v 0 ) (u_0,v_0) 点的灰度值。 在 ( u 0 , v 0 ) (u_0,v_0) 点各相邻像素间灰度变化较小时,这种方法是一

    2024年02月10日
    浏览(52)
  • Python对图像进行灰度处理

    目录 1、解释说明: 2、使用示例: 3、注意事项: 在Python中,我们可以使用PIL(Python Imaging Library)库中的Image模块对图像进行灰度处理。灰度处理是将彩色图像转换为灰度图像的过程,即每个像素的颜色由红、绿、蓝三个通道的值组成,转换为一个单一的灰度值。这样做可以

    2024年02月06日
    浏览(65)
  • Matlab图像处理(1)彩色图像转换为灰度图像(初学必看)

    手把手教你用Matlab实现彩色图像转换为灰度图像 这是一个最基本将彩色图像转换为灰度图像的代码,接下来详细解释代码: ‘RGB’是自己设置的,可以换成另外任何字母可以是a,也可以是b ‘imread’是matlab自带的函数,意思是将后面的对象读入工作区,是必不可少的一步

    2024年02月05日
    浏览(45)
  • 2.matlab图像三种方法灰度值处理

    彩色图像 :每个像素由R、G、B三个分量表示,每个通道取值范围0~255。(通一个彩色图像是由三页组成的,分别是R、G、B,每一页都是一个二维矩阵) 灰度图像 :每个像素只有一个采样颜色的图像,这类图像通常显示为从最暗黑色到最亮的白色的灰度。灰度值分布在0~255之间

    2024年02月15日
    浏览(45)
  • 二、FPGA实时图像处理(灰度转换、高斯滤波、二值化和边缘检测)

    基于图像实时采集系统实现图像处理 算法:采用精度为7的心理学公式:Gray = R 0.299 + G 0.587 + B 0.114, Gray = R 38 + G 75 + B 15 7 采用sobel算子进行边缘检测。 可以通过参数定义修改二值化和边缘检测阈值,以及控制是否进行图像处理和图像处理类型选择。 高斯滤波效果不明显不做演

    2024年02月11日
    浏览(53)
  • Matlab对图像和视频的简单处理(图像视频文件读取和输出,转灰度图,取指定帧的图像)

    语法介绍 : 参数介绍 : filename :要读取的图像文件名,可以是完整的路径。 fmt :可选参数,指定图像的格式。默认情况下,imread会尝试猜测文件格式。常用的格式包括 ‘bmp’、‘gif’、‘jpeg’、‘png’、\\\'tiff’等。 返回值 : A :返回读取的图像数据矩阵,它可以是灰度

    2024年02月06日
    浏览(55)
  • 【数字图像处理】灰度图像中添加高斯噪声、椒盐噪声、斑点噪声以及利用不同方法(中值、排序、维纳滤波)去除各种噪声的matlab程序

    图像处理问题描述: 1、图像中分别加入不同方差的高斯噪声、不同噪声密度椒盐噪声和不同方差的斑点噪声(Gaussian noise, salt  pepper noise and speckle noise) 2、分别通过函数medfilt2、ordfilt2和 Wiener 2 去除图像中添加的一些噪声(Gaussian noise, salt  pepper noise and speckle noise)。 各部

    2024年02月07日
    浏览(57)
  • 基于FPGA的RGB图像转化为灰度图实现,通过MATLAB进行辅助验证

    目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 vivado2019.2 matlab2022a         基于FPGA的RGB图像转换为灰度图实现是一种在图像处理领域常见的操作。这种操作通过将彩色图像的RGB三个通道转换为单一的灰度值,使得图像处理

    2024年02月09日
    浏览(39)
  • FPGA 上使用 SVM 进行图像处理

    面部识别是一个经常讨论的计算机科学话题,并且由于计算机处理能力的指数级增长而成为人们高度关注的话题。面部识别在机器人、生物安全和汽车工业等许多领域都有广泛的应用,涉及对输入图像应用数学算法,提取不同的特征,表明所提供的图片中是否存在人脸。方向

    2024年03月22日
    浏览(49)
  • 如何使用Matlab进行图像处理

    图像处理是操纵图像的数字属性以提高其质量或从图像中获得所需信息的过程。它需要在图像处理应用程序中导入图像,分析图像,然后对图像进行操作,以获得能够产生预期结果的适当输出。 在这篇文章中,我们将讨论使用Matlab进行图像处理和分析的基础知识,以确定图像

    2023年04月10日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包