FPGA-仿真读写bmp图片


最近想完成FPGA图像处理,由于没有开发板,就像通过仿真完成,之前像的是通过python 将图像转化为txt文本,最后利用verilog 读取txt文件导入,对像素点进行处理,然后将处理后像素数据写入txt,最后通过python转化为bmp位图,后来发现verilog可以直接读取bmp文件,并且将数据写入bmp文件。方便了很多。

位图说明

BMP文件存储格式
bmp文件的存储格式是Windows系统中广泛使用的图像文件格式,对图像不做任何程度的压缩处理,主要分为位图头文件,位图信息头,调色板信息,像素数据四大部分,由于通常是处理RBG图像,因此仅讨论RGB的情况

位图头文件 :文件的格式、大小等信息,前14Byte;主要关心的是图像尺寸,像素数据开始位置。
位图信息头: 提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息,前40Byte;主要关心的是图像宽度,图像高度。
调色板信息: 字,不关心
像素数据 : 像素数据,8bit一个像素数据,即1Byte。

在这里插入图片描述

在这里插入图片描述

位图

在这里插入图片描述
我使用的是上面这个128*128

24位位图: 又名RGB真彩色图,又名RGB真彩色图,含2^24=16 777 216=16M色,没有彩色表。每个像素点由3个字节(十六进制码6位)表示,每个字节负责控制一种颜色,分别为蓝(Blue)、绿(Green)、红(Red)。
一幅256×256的24位位图大小计算方法:
位图文件头(14字节)+位图信息头(40字节)+实际像素点占内存(256×256×3字节)=196 662字节(Byte)

注意:
Windows有“补零”的习惯!即要求位图的每一行像素所占字节数必须被4整除。若不能倍4整除,则在该位图每一行的十六进制码末尾“补”1至3个字节的“00”。
例如:一幅宽253×高256的24位位图,微软在生成该图为实际文件时,计算每一行像素所占字节=宽253×3字节=759字节,检验其被4除余1,则在每行的十六进制码末尾加1个字节,补“00”,变为760字节。因此我们计算该图大小时应先判断是否“补零”,再得出算法:
该图大小=位图文件头(14字节)+位图信息头(40字节)+实际像素点占内存(高256×每行760字节)=194614字节(Byte)。
“补零”只针对位图的宽进行检验,一幅宽256×高253的24位位图,
其大小=位图文件头(14字节)+位图信息头(40字节)+实际像素点占内存(高253×每行768字节)=194358字节(Byte)< 196 662字节(Byte)
只是把此图像的宽和高颠倒,图像所占内存竟然变小了。

Verilog代码实现

/*******************************************************************************
*                                                                              *
*     (c) Copyright 1995-2017 TAIHO ELE Co,Ltd.                                *
*     All rights reserved.                                                     *
*                                                                              *
********************************************************************************
*                                                                               
*       FileName     :       top_tb.v                                  
*       Abstract     :       This module is an example for coding.              
*       Author       :       Mouhongbing                                         
*       Version      :       1.1                                                
*       Release      :       2022.9.29                                   
*       Revision     :                                                          
*           Version Date        Author          Modification description        
*           1.0                 Mouhongbing      2022.9.29                
*                                                                               
******************************************************************************/ 
`timescale 1ns / 1ns

module top_tb;

//图像属性:图像宽度 图像高度 图像尺寸 图像像素点起始位
integer bmp_width;
integer bmp_high;
integer bmp_size;
integer start_index;

//bmp file id
integer bmp_file_id;
integer bmp_dout_id;
integer dout_txt_id;

//文件句柄
integer h;
//文件bmp文件数据
reg		[7:0]	rd_data  [0:49300];//根据自己图片大小

//写操作
reg		[23:0]	wr_data;
integer i = 0;
integer index;

initial
begin
    clk=1'b1;
	//打开原始图像
	bmp_file_id = $fopen("D:\\python\\pic\\lena.bmp","rb");
	//打开输出图像
	bmp_dout_id = $fopen("D:\\python\\pic\\output_file.bmp","wb");
	//打开输出数据
	dout_txt_id = $fopen("D:\\python\\pic\\output_file.txt","w+");

	//读取bmp文件
	h = $fread(rd_data,bmp_file_id);

    // 图像宽度
	bmp_width = {
    
    rd_data[21], rd_data[20], rd_data[19], rd_data[18]};
	// 图像宽度
	bmp_high = {
    
    rd_data[25], rd_data[24], rd_data[23], rd_data[22]};
	// 像素起始位置
	start_index = {
    
    rd_data[13], rd_data[12], rd_data[11], rd_data[10]};
	// 图像尺寸
	bmp_size = {
    
    rd_data[5], rd_data[4], rd_data[3], rd_data[2]};
	$fclose(bmp_file_id);



	//输出BMP
	for(i = 0; i < bmp_size; i = i + 1)begin
             $fwrite(bmp_dout_id, "%c", rd_data[i]);//注意参数%c
    end
    $fclose(bmp_dout_id);
    
    //输出txt,只存像素点
    for(index = start_index; index < bmp_size-2; index = index + 3)begin
        wr_data = {
    
    rd_data[index + 2], rd_data[index + 1], rd_data[index]};
        $fwrite(dout_txt_id, "%d,", wr_data[7:0]);
        $fwrite(dout_txt_id, "%d,", wr_data[15:8]);
        $fwrite(dout_txt_id, "%d\n", wr_data[23:16]);
    end
    $fclose(dout_txt_id);
end

endmodule

在这里插入图片描述

python处理代码(附)

图像转txt

扫描二维码关注公众号,回复: 16397926 查看本文章
import cv2     # h, w, c
import numpy
import matplotlib.pyplot as plt

img = cv2.imread("./pic/th.bmp" , 1)
print("图像的形状,返回一个图像的(行数,列数,通道数):", img.shape)
print("图像的像素数目:", img.size)
print("图像的数据类型:", img.dtype)
#img = cv2.resize(img,(280,280))    可以改变图片的大小

fname = open("./pic/th.txt",'w')
# fname.write("图像的形状,返回一个图像的(行数,列数,通道数):"+str(img.shape)+'\n')
# fname.write("图像的像素数目:"+str(img.size)+'\n')
# fname.write("图像的数据类型:"+str(img.dtype)+'\n')
Ylenth = img.shape[1]          # 图片列数
Xlenth = img.shape[0]          # 图片行数

for i in range(Xlenth):
    for j in range(Ylenth):
        fname.write(str(img[i][j][0])+','+str(img[i][j][1])+','+str(img[i][j][2])+'\n')
    # fname.write('\n')
fname.close()


cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

txt转bmp

# -*- coding:utf8 -
from PIL import Image
x = 128    #x坐标  通过对txt里的行数进行整数分解
y = 128  #y坐标  x*y=行数 13500行,150和900也可以
 
im = Image.new("RGB", (x,y))
file = open('./pic/output_file.txt')
 
for i in range(0,x):
    for j in range(0,y):
        #line = file.readline().replace('[','').replace(']','')  #获取一行rgb值,并且把()都替换为空
        line=file.readline()
        rgb = line.split(",") #逗号分割
        im.putpixel((i, j), (int(rgb[2]), int(rgb[1]), int(rgb[0]))) #(i,j)为坐标,后面的是像素点
file.close()
im.save("./pic/output_file.bmp")

猜你喜欢

转载自blog.csdn.net/Mouer__/article/details/127110566
今日推荐