惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
Jina AI
Jina AI
博客园 - 司徒正美
雷峰网
雷峰网
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园_首页
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
I
InfoQ
博客园 - Franky
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
Cyberwarzone
Cyberwarzone
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
P
Privacy & Cybersecurity Law Blog
T
Threatpost
Cloudbric
Cloudbric
D
Docker
M
MIT News - Artificial intelligence
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Vercel News
Vercel News
Martin Fowler
Martin Fowler
J
Java Code Geeks
AWS News Blog
AWS News Blog
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
L
Lohrmann on Cybersecurity
Hacker News: Ask HN
Hacker News: Ask HN
Last Week in AI
Last Week in AI
S
Security @ Cisco Blogs
Help Net Security
Help Net Security
C
Cisco Blogs
V
V2EX
博客园 - 【当耐特】
I
Intezer
爱范儿
爱范儿
F
Fortinet All Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Privacy International News Feed
IT之家
IT之家
L
LINUX DO - 最新话题
B
Blog RSS Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

StrongWong

什么是超低功耗基准测试——ULPMark Benchmark 浅谈 RISC-V 软件开发生态之 IDE 简单了解一下小米 vela wujian100 的 PWM 周期问题 用 Kindle 做树莓派的显示屏 关于 RISC-V 架构下 RTOS 的一些知识 使用 vivado 综合 wujian100 生成 bitstream 文件 Windows 下学习阿里平头哥 RISC-V 芯片开发平台 wujian100 拆解一个很有意思的开关 拆解某宝上热销的一款蓝牙耳机 Archives Windows10 环境下搭建 RISC-V 调试环境 Contact 使用汇编实现 pc 和 sp 的保存及恢复操作 数字 IC 设计流程 SDRAM 两次踏进同一条河 初窥 SDRAM 从计数器开始,看数字 IC 设计 使用 Docker + GitLab 构建自用的代码管理服务 提升数字 IC 设计效率从 Vim 开始 总线- SoC 内部的主干道 Tools 使用树莓派 3b 和 RTL_SDR 搭建小功率无线电监测点 关于 ARM Cortex-M3 的启动文件分析及分散加载 make 命令及 makefile 文件编写 ROS 基础知识 在 Jetson TX2 上安装 ROS 机器人操作系统 Jetson TX2 重新编译内核添加usb等驱动 Nvidia Jetson TX2 刷机并安装JetPack3.1 我的毕业设计--基于ROS的移动机器人 使用 Hexo+Github Pages 搭建个人博客 About
FPGA 数字图像处理联合仿真平台的搭建及使用举例
BH6BAO · 2019-09-03 · via StrongWong

· BH6BAO

前言

随着物联网技术的不断发展,对边缘计算的性能要求愈发苛刻,传统的 IoT 级别的 SoC 或者 MCU 难以应对诸如图像识别的场景需求,因此 FPGA + MCU 或 FPGA + SoC 的异构架构愈来愈多地应用于上述场景中,以满足相关需求。(以上这段话毫无意义,只是为了凑字数,另外为了纪念第三次憾负的开场白)

当前 FPGA 发展火热,众多开发者使用 FPGA 来完成部分图像处理的部分功能,但众所周知纯 FPGA 开发(或者数字 IC 设计)与常见的 ARM A 系列(with OS)或者桌面端 PC 在图像处理开发过程中最大的差别在于过程的可视化。开发过程中的可视化多少会影响到开发者对于图像处理的判断与取舍,简而言之,如果开发者都不知道经过了这一步处理后图像变成了什么样,那还如何继续接下来的步骤。因此分享交流一下在本次车牌识别设计中我们所用到的数字图像处理的联合仿真平台(注:本文仅仅介绍平台使用方式,不介绍过程中涉及到的数字图像处理原理),如果有更好的方式,希望大家可以留言给予建议~

首先是我们所需要的软件工具:

本次我们的开发环境为 Win10 所用到的软件工具分别为:Modelsim(10.5B), MATLAB(R2019a)

然后简述一下我们的操作过程(以图片 RGB 色域转换 YCbCr 色域处理为例),整体过程可简述如下:通过 MATLAB 将图片文件转换为 .txt 格式文件,使用 Verilog 读取相应文件后完成相应图像处理操作后输出为 .txt 文件,再次使用 MATLAB 将输出的 .txt 格式文件转换为图片文件并查看。以上步骤的意义在于不仅可以实现数字图像处理的单步可视化,还可以同原始的 MATLAB 对应的处理效果进行对比。(后期我们也会更新,直接使用 Verilog 完成图像读取并输出结果查看的方法)

首先我们通过以下程序(亦可查看附带工程中的 IMG2TXT.m 文件)在 MATLAB 端将图片生成 R,G,B 色域对应的 .txt 格式文件。并同时通过 MATLAB 生成 YCbCr 色域下三个分量的图像予以显示。 其关键代码如下:

clear all
close all
clc
img = imread('test.jpg');
[a,b,c]= size(img);
R1=img(:,:,1);
G1=img(:,:,2);
B1=img(:,:,3);

fidR1= fopen('testR.txt','w');
fidG1= fopen('testG.txt','w');
fidB1= fopen('testB.txt','w');
for i=1:a
    for j= 1:b
      fprintf(fidR1,'%d\n',R1(i,j)); %frame1
      fprintf(fidG1,'%d\n',G1(i,j));
      fprintf(fidB1,'%d\n',B1(i,j));
    end
end
fclose(fidR1);
fclose(fidG1);
fclose(fidB1);

RGB 色域文件生成

生成对应 RGB 色域 .txt 格式文件如下图所示:

RGB.txt

生成 YCbCr 色域对应分量图片(详见工程文件 YCbCr.m ),如下图所示:

YCbCr

Verilog 处理

然后在我们的 Modelsim 工程中对 .txt 格式文件进行读取(亦可查看工程中附带的 imread.v 文件),进一步的完成图像处理对应的操作后,输出对应 .txt 格式文件(亦可查看工程中附带 imwrite.v 文件)。 其 txt 读取关键代码如下:

initial begin
  fR = $fopen("testR.txt","r");   // read in testR.txt
  fG = $fopen("testG.txt","r");
  fB = $fopen("testB.txt","r");
  if(fR == `NULL || fG == `NULL || fB == `NULL) begin
    $display("data_file handle was NULL");
	$finish;
  end
  else begin
    $fscanf(fR,"%d;\n",R);
	$fscanf(fG,"%d;\n",G);
	$fscanf(fB,"%d;\n",B);
  end
end

always @(posedge pixel_clk or negedge reset_n) begin
  if(reset_n == 0) begin
    R = 8'd0;
	G = 8'd0;
	B = 8'd0;
  end
  else if(de) begin
    if(fR != 0 && fG != 0 && fB != 0) begin
	 $fscanf(fR,"%d;\n",R);
	 $fscanf(fG,"%d;\n",G);
	 $fscanf(fB,"%d;\n",B);
	 $display("time=[%d],%d,%d,%d",$realtime,R,G,B);
	end
  end

end

完成处理后生成 txt 关键代码如下:

initial begin
  fR = $fopen("R.txt","w");
  fG = $fopen("G.txt","w");
  fB = $fopen("B.txt","w");
  if(fR == `NULL || fG == `NULL || fB == `NULL) begin
    $display("can not open R.txt or G.txt or B.txt");
	$finish;
  end
end

always @(posedge pixel_clk or negedge reset_n) begin
  if(de) begin
    $display("////////////////////////////////////");
    $display("time=[%d],%d,%d,%d",$realtime,R,G,B);
    $fwrite(fR,"%d\n",R);
	$fwrite(fG,"%d\n",G);
	$fwrite(fB,"%d\n",B);
  end
end

处理结果

最终在 MATLAB 端将仿真生成输出的 .txt 文件转换还原为图片(亦可查看工程中附带的 TXT2IMG.M 文件)。

clear all
close all
clc

imgori = imread('test.jpg');
[a,b,c]= size(imgori);

img1R = uint8(textread('R.txt','%u'));
img1G = uint8(textread('G.txt','%u'));
img1B = uint8(textread('B.txt','%u'));

img1(:,:,1) = reshape(img1R,[b,a]);
img1(:,:,2) = reshape(img1G,[b,a]);
img1(:,:,3) = reshape(img1B,[b,a]);

img=flipdim(img1,1);

figure,
subplot(221),imshow(imrotate(img,-90)),title('YCbCr');
subplot(222),imshow(imrotate(img(:,:,1),-90)),title('Y');
subplot(223),imshow(imrotate(img(:,:,2),-90)),title('Cb');
subplot(224),imshow(imrotate(img(:,:,3),-90)),title('Cr');

由于常见的 FPGA 数字图像处理为了减少数据读取对于缓存资源的消耗,通常其处理步骤在视频流完成,因此本次工程中我们在 VGA 模拟时序中完成相应操作。完成仿真如波形下图所示:

Waveform

生成结果 .txt 文件如下图所示: Outfile

将生成结果 .txt 文件放回 MATLAB 工程路径下最终实现效果如下图所示:

Outfile of FPGA

MATLAB vs HDL数字图像处理 结果对比

将图像放大后,可以明显发现通过数字思想处理得到的图片结果相较于 MATLAB 直接转换得到的结果存在一定的差距,Cr 分量下表现的最为明显,具体原因在此不具体展开分析。其对比如下图(注:左侧为 MATLAB 处理结果右侧为 verilog 处理结果

Matlab vs HDL

之后我们将逐步介绍本次我们 ARM 杯车牌识别系统的每个实现过程~

并公开全套设计源码!!!

举例部分全部代码详见 GitHub 仓库:https://github.com/strongwong/FPGA-DIP

By Ricky