用matlab和modelsim仿真图像处理的一些注意事项

本文介绍了如何使用FPGA通过Modelsim进行图像数据的仿真,包括将图片转换为文本输入处理模块,以及后续的MATLAB处理和问题排查。作者详细展示了数据产生模块的实现,并提到了MATLAB中读取数据时遇到的问题及解决方案。
摘要由CSDN通过智能技术生成

FPGA处理图像,可以先用modelsim仿真一下,就是原始图片转换成txt文档,把文档数据作为输入,通过自己写的处理模块后得到输出的txt文档数据,再使用matlab把文档转换成图片,查看写的模块是否正确。

第一步就是写一个数据产生模块,为了和视频数据流格式统一,在行同步和场同步期间写数据。这里借鉴这位博主的数据产生模块:Jane Laki Zder,把数据读到寄存器image中

添加链接描述

`timescale 1ns/1ps
`define VIDEO_1920_1080
module sim_image(
    input       wire                    pclk    ,
    output      wire            [02:00] vs_o    ,
    output      wire            [23:00] ds_o    
);
 
//1920x1080 148.5Mhz
`ifdef VIDEO_1920_1080
parameter   H_ACTIVE        = 1920; // 行数据有效时间
parameter   H_FRONT_PORCH   = 88;   // 行消隐前肩时间
parameter   H_SYNC_TIME     = 44;   // 行同步信号时间
parameter   H_BACK_PORCH    = 148;  // 行消隐后肩时间
 
parameter   V_ACTIVE        = 1080; // 列数据有效时间
parameter   V_FRONT_PORCH   = 4;    // 列消隐前肩时间
parameter   V_SYNC_TIME     = 5;    // 列同步信号时间
parameter   V_BACK_PORCH    = 36;   // 列消隐后肩时间
`endif 
//1280X720 74.25MHZ
`ifdef  VIDEO_1280_720
parameter  H_ACTIVE 		= 1280; // 行数据有效时间
parameter  H_FRONT_PORCH 	= 110;  // 行消隐前肩时间
parameter  H_SYNC_TIME 		= 40;   // 行同步信号时间
parameter  H_BACK_PORCH 	= 220;  // 行消隐后肩时间    
 
parameter  V_ACTIVE 		= 720;  // 列数据有效时间
parameter  V_FRONT_PORCH 	= 5;    // 列消隐前肩时间
parameter  V_SYNC_TIME  	= 5;    // 列同步信号时间
parameter  V_BACK_PORCH 	= 20;   // 列消隐后肩时间
`endif
 
parameter  H_TOTAL_TIME 	= H_ACTIVE + H_FRONT_PORCH + H_SYNC_TIME + H_BACK_PORCH; 
parameter  V_TOTAL_TIME 	= H_ACTIVE + V_FRONT_PORCH + V_SYNC_TIME + V_BACK_PORCH;
 
 
reg             o_hs;
reg             o_vs;
reg             o_de,o_deo;
reg     [07:00] o_rr;
reg     [07:00] o_gg;
reg     [07:00] o_bb;
reg     [12:00] h_syn_cnt   = 'd0;
reg     [12:00] v_syn_cnt   = 'd0;
reg     [23:00] image [0:H_ACTIVE*H_ACTIVE - 1];
reg     [31:00] image_cnt = 'd0;
initial begin
    $readmemh("E:/D_desktop/mmworkspcae/matlab_src/image_1080_1920_3.txt",image);
end
always @(posedge pclk) begin
    if (h_syn_cnt == H_TOTAL_TIME - 1) 
        h_syn_cnt <= 0;
    else
        h_syn_cnt <= h_syn_cnt + 1;
end
always @(posedge pclk) begin
    if (h_syn_cnt == H_TOTAL_TIME - 1) begin
        if (v_syn_cnt == V_TOTAL_TIME - 1) 
            v_syn_cnt <= 0;
        else
            v_syn_cnt <= v_syn_cnt + 1;
    end
end
always @(posedge pclk) begin
    if (h_syn_cnt < H_SYNC_TIME) 
        o_hs <= 0;
    else
        o_hs <= 1;
end
always @(posedge pclk) begin
    if (v_syn_cnt < V_SYNC_TIME)
        o_vs <= 0;
    else
        o_vs <= 1;
end
always@(posedge pclk)begin
    if(v_syn_cnt >= V_SYNC_TIME + V_BACK_PORCH && v_syn_cnt < V_SYNC_TIME + V_BACK_PORCH + V_ACTIVE)
    begin
        if(h_syn_cnt >= H_SYNC_TIME + H_BACK_PORCH && h_syn_cnt < H_SYNC_TIME + H_BACK_PORCH + H_ACTIVE)
            o_de <= 1;
        else
            o_de <= 0;
    end
    else
        o_de <= 0;
end
always @(posedge pclk) begin
    if (o_de) begin
        o_rr <= image[image_cnt][23:16];
        o_gg <= image[image_cnt][15:08];
        o_rr <= image[image_cnt][07:00];
        image_cnt <= image_cnt + 1;
    end
    else if (image_cnt == H_ACTIVE*V_ACTIVE) begin
		o_rr <= 8'h00;
		o_gg <= 8'h00;
		o_bb <= 8'h00;
        image_cnt <= 'd0;
    end
    else begin
		o_rr <= 8'h00;
		o_gg <= 8'h00;
		o_bb <= 8'h00;
        image_cnt <= image_cnt;
    end
end
 
always @(posedge pclk) o_deo <= o_de;
 
assign vs_o = {o_hs,o_vs,o_de};
assign ds_o = {o_rr,o_gg,o_bb};
endmodule

数据产生模块好了之后就是处理模块,这里简单用rgb转灰度试一下,代码就是我之前写过的。

写一个顶层文件,例化模块。然后在modelsim中新建工程,编写tb文件,步骤和上面提到的博主一样,仿真步骤就好了。

随后就是用matlab读取和产生txt文件了,这里我也是用这位博主的matlab程序,但是仿真后却无法读出txt文档,查看波形发现过一段时间后,产生的data都是XXXXX,查看源头image也是这样,直接打开文档看看只有一百万个数据,远小于应该的1920*1080个。原来是在matlab运行中直接打开“image_1080_1920_3.txt”这个文件会导致数据不会再写入文档,只要等一会数据写完即可。

 
clear;clear all;clc;
 
image_in = imread('origin_image.jpg');  
     
 
FileName=['image_',num2str(size(image_in,1)),'_',num2str(size(image_in,2)),'_',num2str(size(image_in,3)),'.txt'];
 
[row,col,n] = size(image_in);
 
fid = fopen(FileName,'w');  
 
for x = 1:row
	for y = 1:col
		image_R = dec2hex(image_in(x,y,1));
		image_G = dec2hex(image_in(x,y,2));
		image_B = dec2hex(image_in(x,y,3));
		
		[rm,rn]=size(image_R);
		[gm,gn]=size(image_G);			
		[bm,bn]=size(image_B);
		
		if rn == 1
			image_R =['0',image_R];
		elseif rn == 0
			image_R ='00';
		end
		if gn == 1
			image_G =['0',image_G];
		elseif gn == 0
			image_G ='00';
		end			
		if bn == 1
			image_B =['0',image_B];
		elseif bn == 0
			image_B ='00';
		end			
		
		image_hex=[image_R,image_G,image_B];
		fprintf(fid,'%s\n',image_hex);
	end
end
fclose(fid);

rgb转灰度后有三个分量ycbcr,用rgb显示灰度图像把三个通道都设置为Y即可显示灰度图像。

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值