当前位置:   article > 正文

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

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

数据产生模块好了之后就是处理模块,这里简单用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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/740991
推荐阅读
相关标签
  

闽ICP备14008679号