Matlab与ModelSim图像处理验证
仿真系统搭建
1 系统框图
2 VGA时序发生器
由于图像处理电路都是基于VGA时序,所以在仿真平台中,需要有一个源VGA信号发生器,模仿VGA的时序。其模块基本属性如下所示:
`define pix_800_600
modulevga_ctl
(
input pix_clk,
input reset_n,
input [23:0] VGA_RGB,
output VGA_CLK,
output [11:0] hcount,
output [11:0] vcount,
output [7:0] VGA_R,
output [7:0] VGA_G,
output [7:0] VGA_B,
output VGA_HS,
output VGA_VS,
output VGA_DE,
output BLK
);
`include "vga_parameter.vh"
对应不同分辨率,我们需要不同的VGA标准参数,这些参数定义在vga_parameter.vh文件中,例如本仿真平台处理的图像数据为800*600:则该文件中应有如下参数的定义:
`ifdef pix_800_600
//---------------------------------//
// 800*600 60HZ pixel clock 40.00MHZ
//--------------------------------//
parameter H_Total = 1056;
parameter H_Sync = 128;
parameter H_Back = 88;
parameter H_Active = 800;
parameter H_Front = 40;
parameter H_Start = 216;//H_Sync+H_Back
parameter H_End = 1016;//H_Sync+H_Back+H_Active
//-------------------------------//
// 800*600 60HZ
//-------------------------------//
parameter V_Total = 628;
parameter V_Sync = 4;
parameter V_Back = 23;
parameter V_Active = 600;
parameter V_Front = 1;
parameter V_Start = 27;//V_Sync+V_Back
parameter V_End = 627;//V_Sync+V_Back+V_Active
`endif
3图像数据转换
我们需要将待处理的图像,转换成为VGA能够解析的数据流,这部分利用Matlab实现数据格式的转换。在工作目录执行img_txt.m脚本,脚本执行结束之后,有如上图所示效果。其中img为拍摄的原图,R、G、B为三个通道的灰度图。并在工作目录下生成如下图所示的文件:
为了读取这些文件,我们需要编写verilog软件程序,把它们转换成RGB格式输出到VGA的RGB输出端。其模块基本属性如下:
`timescale 1ns/1ps
`define NULL 0
moduleimread_frame1(
input pixel_clk,
input reset_n,
input de,
input [11:0] frame_cnt,
output [23:0] rgb
);
经过上述几个步骤,我们已经能够把一幅图像以VGA时序进行输出,至此已经搭建出了图像仿真系统的雏形,并且为了将经过verilog处理的图像以可视化的形式展现,还需要有verilog写入图像数据的软件程序,其模块基本属性如下:
`timescale 1ns/1ps
`define NULL 0
moduleimwrite_frame4(
input pixel_clk,
input reset_n,
input de,
input [11:0] frame_cnt,
input [23:0] rgb
);
该程序会在图像处理的过程中,将数据缓存到工作目录,并且例化多个写图像的模块,即可观察到图像处理的过程,其缓存结果如下:
最后,我们需要将verilog保存的文件利用matlab脚本txt_img.m转换成可视化的图片,观察verilog处理过程是否正确。最后显示处理结果如下
图像处理仿真
1 RGB转YCbCr
为了方便进行图像阈值的提取,利用verilog实现了RGB到YCbCr的色域转换,计算式可以百度:
其效果如下图所示
rgb2ycbcr U_rgb2ycbcr(
.pixelclk(pixel_clk),
.i_rgb(VGA_RGB),
.i_hsync(VGA_HS),
.i_vsync(VGA_VS),
.i_de(VGA_DE),
.o_rgb(y_rgb),
.o_ycbcr(y_ycbcr),
.o_gray(y_gray),
.o_hsync(y_o_hsync),
.o_vsync(y_o_vsync),
.o_de(y_o_de));
2 阈值确定与二值化
首先将车牌从复杂的环境中提取出来。确定车牌的阈值,二值化。
ycbcr_location#( //Paramter Define such as threshold
)U_ycbcr_location(
.pixelclk(pixel_clk),
.reset_n(reset_n),
.i_rgb(y_rgb),
.i_ycbcr(y_ycbcr),
.i_gray(y_gray),
.i_hsync(y_o_hsync),
.i_vsync(y_o_vsync),
.i_de(y_o_de),
.binary_image(yl_binary),
.rgb_image(yl_rgb),
.gray_image(yl_gray),
.o_hsync(yl_o_hsync),
.o_vsync(yl_o_vsync),
.o_de(yl_o_de)
);
3 锁定车牌位置
通过水平垂直投影,可以将车牌框选出来,并且为了便于识别数字,我们将车牌以外的颜色转换成近似车牌的底色,便于进行第二次的垂直投影与阈值提取。此外,框选车牌的同时,削掉了一部分上下边界,去除了定孔。
Vertical_Projection#( //Paramter Define such as threshold
)U_Vertical_Projection(
.pixelclk(pixel_clk),
.reset_n(reset_n),
.i_binary(HV_dout),
.i_hs(HV_o_hsync),
.i_vs(HV_o_vsync),
.i_de(HV_o_de),
.i_hcount(hcount),
.i_vcount(vcount),
.hcount_l(hcount_l),
.hcount_r(hcount_r),
.vcount_l(vcount_l),
.vcount_r(vcount_r));
可在modelsim中观察仿真波形图如下:
可以看到,车牌的水平边界和垂直边界都被取出,分别对应为hcount_l, hcount_r, vcount_l, vcount_r这几个信号。
4 提取车牌数字
这次,我们重复进行一次色域的转换,在YCbCr色域下提取出车牌内的字符,效果如下图所示,至此我们已经提取出了复杂场景下的车牌字符。
5 水平垂直投影
对已经经过二值化的车牌字符图像,我们例化一个能够检测八个边界的水平垂直投影模块。其垂直投影后的效果如下图所示
至此,我们可以将八个字符一个一个的分割,进行单独的数字识别处理,极大的简化了处理的难度。接下来介绍本工程中采用的两种数字识别的方案。
6 方案一:数字特征识别
本方案已经上板实现,但是仍然存在缺陷,比如说仅仅能识别数字,且识别条件较为苛刻,需要现场调试一段时间。
7 方案二:5X8维矩阵检测
对单个数字进行画框操作,并且统计出每个小格子的像素点数目,超过该格子的一半则认为是1,少于则认为是0。下图为5的画框仿真。
在modelsim中观察仿真波形,则5的数字模型被正确识别,并且对于同一字体其数字特征值应相同。
相关工程文件可以去我的个人博客下载: 点击前往
- 上一篇 »PHP图像处理之画图
- 下一篇 »PHP图片裁剪、无损调整图片大小