Verilog读取bmp图片

在没有开发板的情况下,要使用Verilog做图像处理,就只能仿真了。

这时需要一个激励,让Verilog读取到图片,这里就提供一个例子去读取bmp图片。

`timescale 1ns / 1ns

module bmp_tb;

integer iBmpFileId,iOutFileId,iIndex=0,iCode;
reg [7:0] rBmpData [0:200000];
reg rClk;
reg [7:0] rData;
integer iBmpWidth,iBmpHight,iDataStartIndex,iBmpSize;

initial begin
	iBmpFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\cat.bmp","rb");
	iOutFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\output_file.txt","w+");

	iCode = $fread(rBmpData,iBmpFileId);

	iBmpWidth = {rBmpData[21],rBmpData[20],rBmpData[19],rBmpData[18]};
	iBmpHight = {rBmpData[25],rBmpData[24],rBmpData[23],rBmpData[22]};
	iDataStartIndex = {rBmpData[13],rBmpData[12],rBmpData[11],rBmpData[10]};
	iBmpSize = {rBmpData[5],rBmpData[4],rBmpData[3],rBmpData[2]};

	$fclose(iBmpFileId);
	$fwrite(iOutFileId,"%p",rBmpData);
        $fclose(iOutFileId);
end

initial begin
	forever begin
			rClk=1;
		#10 rClk = 0;
		#10;
	end // forever 
end // initial

always@(posedge rClk) begin
	rData<=rBmpData[iIndex];
	iIndex<=iIndex+1;
end

endmodule

注意:其中iBmpFileId和iOutFileId的路径,需要根据你的文件路径而修改。

经过仿真,可以看出Verilog可以读取到bmp图片的信息,从而得到图片的宽、高。

若要输出.bmp图片,可以使用以下代码。

`timescale 1ns / 1ns

module bmp_tb;

integer iBmpFileId,iOutFileId,iIndex=0,iCode;
reg [7:0] rBmpData [0:200000];
reg [31:0] rBmpCom;
reg rClk;
reg [7:0] rData;
integer iBmpWidth,iBmpHight,iDataStartIndex,iBmpSize;

initial begin
	iBmpFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\cat.bmp","rb");
	iOutFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\output_file.bmp","w+");
	iCode = $fread(rBmpData,iBmpFileId);
	iBmpWidth = {rBmpData[21],rBmpData[20],rBmpData[19],rBmpData[18]};
	iBmpHight = {rBmpData[25],rBmpData[24],rBmpData[23],rBmpData[22]};
	iDataStartIndex = {rBmpData[13],rBmpData[12],rBmpData[11],rBmpData[10]};
	iBmpSize = {rBmpData[5],rBmpData[4],rBmpData[3],rBmpData[2]};
	$fclose(iBmpFileId);

	for (iIndex = 0; iIndex < iBmpSize; iIndex = iIndex + 4) begin
		rBmpCom = {rBmpData[iIndex+3],rBmpData[iIndex+2],rBmpData[iIndex+1],rBmpData[iIndex]};
		$fwrite(iOutFileId,"%u",rBmpCom);
	end // for
	$fclose(iOutFileId);
end

endmodule

使用的图片,如下图所示,请保存为.bmp格式。

其中输出的.bmp图片中,多了一个字节(0A前面多了0D),会显示如下图所示。

 

解决办法是使用二进制方法打开文件,即wb+,代码如下:

`timescale 1ns / 1ns

module bmp_tb;

integer iBmpFileId,iOutFileId,iIndex=0,iCode;
reg [7:0] rBmpData [0:200000];
reg [31:0] rBmpCom;
reg rClk;
reg [7:0] rData;
integer iBmpWidth,iBmpHight,iDataStartIndex,iBmpSize;

initial begin
	iBmpFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\cat.bmp","rb+");
	iOutFileId = $fopen("G:\\WorkDir\\ProQuestaSim\\bmp_sim\\src\\output_file.bmp","wb+");
	iCode = $fread(rBmpData,iBmpFileId);
	iBmpWidth = {rBmpData[21],rBmpData[20],rBmpData[19],rBmpData[18]};
	iBmpHight = {rBmpData[25],rBmpData[24],rBmpData[23],rBmpData[22]};
	iDataStartIndex = {rBmpData[13],rBmpData[12],rBmpData[11],rBmpData[10]};
	iBmpSize = {rBmpData[5],rBmpData[4],rBmpData[3],rBmpData[2]};
	$fclose(iBmpFileId);

	for (iIndex = 0; iIndex < iBmpSize; iIndex = iIndex + 4) begin
		rBmpCom = {rBmpData[iIndex+3],rBmpData[iIndex+2],rBmpData[iIndex+1],rBmpData[iIndex]};
		$fwrite(iOutFileId,"%u",rBmpCom);
	end // for
	$fclose(iOutFileId);
end

endmodule

利用这一方法,可以输出直方图、时域图、频域图等,如:使用可综合语句完成FFT的功能,再使用tb让其输出频域图。

 

  • 17
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值