ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

使用matlab将图片转化成.coe文件,将.coe文件转化成图片(VIVADO-FPGA-ROM IP核)

使用matlab将图片转化成.coe文件,将.coe文件转化成图片(VIVADO-FPGA-ROM IP核)

在使用ROM IP核(配置请看上一节)时,需要我们上传。coe文件存储在块ROM里面,那怎样把一张图片转化成coe格式呢?我们可以借助MATLAB来实现。将下面的代码1保存为函数,在命令行运行一下代码2,即可得到指定图片的coe文件。

代码1:

% 彩色图片转COE文件(行优先顺序) % 输入参数:图片路径、输出COE路径、目标分辨率[height, width]、RGB位宽[R_bits, G_bits, B_bits] function img2rgb_coe(img_path, coe_path, target_res, rgb_bits) % 1. 读取图片并转换为RGB格式 img = imread(img_path); if size(img, 3) ~= 3 error('请输入彩色图片(RGB格式)'); end img = im2double(img); % 转换为0-1浮点数 % 2. 缩放图片至目标分辨率 img_resized = imresize(img, target_res, 'bilinear'); % 双线性插值缩放 [height, width, ~] = size(img_resized); fprintf('图片已缩放至分辨率:%d×%d\n', height, width); % 3. 解析RGB位宽并验证合法性 R_bits = rgb_bits(1); G_bits = rgb_bits(2); B_bits = rgb_bits(3); total_bits = R_bits + G_bits + B_bits; if total_bits > 32 || R_bits < 1 || G_bits < 1 || B_bits < 1 error('RGB位宽需为正整数,且总位宽不超过32'); end fprintf('RGB位宽配置:R%dG%dB%d(总位宽:%dbit)\n', R_bits, G_bits, B_bits, total_bits); % 4. 量化RGB通道数据(映射到指定位宽的整数范围) R_quant = round(img_resized(:, :, 1) * (2^R_bits - 1)); % 0~2^R_bits-1 G_quant = round(img_resized(:, :, 2) * (2^G_bits - 1)); % 0~2^G_bits-1 B_quant = round(img_resized(:, :, 3) * (2^B_bits - 1)); % 0~2^B_bits-1 % 5. 拼接RGB数据(按R→G→B顺序拼接为一个整数) img_packed = bitshift(R_quant, G_bits + B_bits) ... + bitshift(G_quant, B_bits) ... + B_quant; % height×width 矩阵 % 【行优先】把矩阵按行展开成 1×(height*width) 向量 img_packed = reshape(img_packed.', 1, []); % 先转置再按列展开 = 行优先 % 6. 生成COE文件(Xilinx标准格式) fid = fopen(coe_path, 'w'); if fid == -1 error('无法创建COE文件,请检查路径权限'); end fprintf(fid, 'memory_initialization_radix = 16;\n'); fprintf(fid, 'memory_initialization_vector =\n'); pixel_count = height * width; for i = 1:pixel_count hex_str = dec2hex(img_packed(i), ceil(total_bits / 4)); if i == pixel_count fprintf(fid, '%s;\n', hex_str); else fprintf(fid, '%s,\n', hex_str); end end fclose(fid); fprintf('COE文件已生成(行优先顺序):%s\n', coe_path); end

代码2:(用于命令行运行)

img_path = 'color.png'; %指定图片路径,记得放在当前路径下 coe_path = 'color.coe'; %coe文件路径 target_res = [240, 320]; % [高, 宽] rgb_bits = [4 4 4]; % R4 G4 B4 img2rgb_coe(img_path, coe_path, target_res, rgb_bits);

保存代码1,运行代码2,即可得到指定图片的coe文件。当然已经转化好的原图片和对应coe文件可以从评论区下载,我会上传到评论区。

如果你想检验一下你的coe文件会转化成什么样的图片,可以运行下面代码3,进行查看

代码3:(只需要将代码最前面的4个参数更改成与你的代码相对应的,即可运行)

%% 参数区 —— 用户只需改这里 4 个量 fileName = 'color.coe'; % 输入 COE 文件 imgWidth = 320; % 图像宽度(像素) imgHeight = 240; % 图像高度(像素) rgbBits = [4 4 4]; % [R, G, B] 各自的位宽,常见如 565、888 等 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 1. 读文件,只保留十六进制数据行 fid = fopen(fileName,'r'); assert(fid>0,'无法打开文件:%s',fileName); tline = fgetl(fid); hexData = {}; while ischar(tline) % 去掉注释(; 后的内容)以及首尾空格 tline = strtrim( regexprep(tline,';.*','') ); % 如果是纯十六进制行(允许逗号结尾),就收下 if ~isempty(tline) && ~isempty( regexp(tline,'^[0-9a-fA-F]+[,]?$','once') ) hexData{end+1} = strrep(tline,',',''); %#ok<AGROW> end tline = fgetl(fid); end fclose(fid); totalPix = numel(hexData); expectedPix = imgWidth*imgHeight; assert(totalPix==expectedPix,... 'COE 数据量(%d)与分辨率(%d×%d=%d)不符',totalPix,imgWidth,imgHeight,expectedPix); %% 2. 十六进制字符串 → 十进制整数 raw = cellfun(@(s) sscanf(s,'%x'), hexData); % 1×N 向量 %% 3. 按位宽把像素拆成 R/G/B rBits = rgbBits(1); gBits = rgbBits(2); bBits = rgbBits(3); totalBits = rBits + gBits + bBits; assert(totalBits<=32,'总位宽不能超过32'); maskR = bitshift(1,rBits)-1; maskG = bitshift(1,gBits)-1; maskB = bitshift(1,bBits)-1; R = bitand( bitshift(raw,-(gBits+bBits)), maskR ); G = bitand( bitshift(raw,-bBits), maskG ); B = bitand( raw, maskB ); %% 4. 归一化到 0~1 双精度 R = double(R) / maskR; G = double(G) / maskG; B = double(B) / maskB; %% 5. 拼成 3-D RGB 矩阵并显示/保存 RGB = cat(3, ... reshape(R,imgWidth,imgHeight).', ... reshape(G,imgWidth,imgHeight).', ... reshape(B,imgWidth,imgHeight).'); figure; imshow(RGB); title('COE 还原图像'); imwrite(RGB,'coe_out.png'); % 同时保存成文件 disp('Done!已保存为 coe_out.png');

1. 原图片:

2. .coe文件见评论区网盘链接(8.coe)

3. 使用.coe显示出来会有点失真,图片如下:

4.将原图转化成灰度图片

5.该黑白灰图片的coe文件也会放在评论区(16.coe)

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进