当前位置:   article > 正文

linux 正点原子ov5640_「正点原子FPGA连载第二十六章基于OV5640的二值化实验

ov5640原理图

1)摘自【正点原子】领航者 ZYNQ 之嵌入式开发指南

2)实验平台:正点原子领航者ZYNQ开发板
3)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761
4)全套实验源码+手册+视频下载:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html
5)对正点原子FPGA感兴趣的同学可以加群讨论:876744900
6)关注正点原子公众号,获取最新资料

5154044f5aba71daded3ef26ff9affcf.png

第二十六章基于OV5640的二值化实验
在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,还能凸显出目标的轮廓。图像二值化在计算机视觉、图像分割以及人工智能等方面有着广泛应用。在本章节我们将进行基于OV5640的二值化实验。
本章包括以下几个部分:
234567891011121314151617181920212223242526272626.1简介
26.2实验任务
26.3硬件设计
26.4程序设计
26.5下载验证
26.1简介
图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为最大(白色)或最小(黑色),也就是将整个图像呈现出明显的黑白效果的过程。这里我们以8bit表示的灰度图像为例(灰度值的范围为0~255),二值化就是通过选取适当的阈值,与图像中的256个亮度等级进行比较。亮度高于阈值的像素点设置为白色(255),低于阈值的像素点设置为黑色(0),从而明显地反映出图像的整体和局部特征。
在数字图像处理中,二值图像占有非常重要的地位,特别是在实时的图像处理中,通过二值图像处理实现而构成的系统是很多的。要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样有利于在对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。所有灰度大于或等于阈值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。
实现二值化有两种方法,一种是手动指定一个阈值,通过阈值来进行二值化处理;另一种是一个自适应阈值二值化方法(OTSU算法和Kittle算法等)。使用第一种方法计算量小速度快,但在处理不同图像时颜色分布差别很大;使用第二种方法适用性强,能直接观测处图像的轮廓,但相对计算更复杂。本章节实验我们将使用第一种方法来实现图像的二值化。
如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用制定阈值的方法,可以得到比较有效的分割效果。如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阈值选取技术来分割该图像。
26.2实验任务
用OV5640摄像头采集RGB565数据,将数据转化成Ycbcr格式,然后进行灰度二值化,并通过LCD屏显示。
26.3硬件设计
本次实验我们是基于“OV5640摄像头LCD显示实验”进行图像处理的,实验的系统框图与“OV5640摄像头LCD显示实验”基本相同,我们只是添加了“VIP(video image process)”模块,实验系统框图如下:

05d517a8eb1bd7b1ca9df927012b2cd7.png

图 26.3.1 系统框图


图中“RGB转Ycbcr”模块与“OV5640摄像头LCD显示实验”相同,其作用就是为了将RGB565数据转化成Ycbcr的数据,便于提取灰度。“二值化”模块用于实现灰度图像的二值化。
下图是VIP(video image process)在“Block Design”中的链接图:

df4b4a53198c7d12d93ed64e75fb2016.png


图 26.3.2 基于OV5640的二值化实验原理图


VIP(video image process)模块调用了“rgb2ycbcr”和“binarization”两个模块,下图是VIP内部,“rgb2ycbcr”和“binarization”模块的连接图:

c4ae1153dddf14ca71f179cd10bb5b37.png

图 26.3.3 VIP模块内部连接图


VIP模块顶层代码如下:

  1. 1 module Video_Image_Processor(
  2. 2 input clk, //cmos 像素时钟
  3. 3 input rst_n,
  4. 4
  5. 5 //预处理图像
  6. 6 input pre_image_vsync, //预处理图像场同步信号
  7. 7 input pre_image_clken, //预处理图像时钟使能信号
  8. 8 input pre_data_valid, //预处理图像数据有效信号
  9. 9 input [23:0] pre_image_data, //预处理图像数据
  10. 10
  11. 11 //处理后图像
  12. 12 output pos_image_vsync, //处理后图像场同步信号?
  13. 13 output pos_image_clken, //处理后图像时钟使能信号
  14. 14 output pos_data_valid, //处理后图像数据有效信号
  15. 15 output [23:0] pos_image_data //处理后图像数据
  16. 16
  17. 17 );
  18. 18
  19. 19 //wire define
  20. 20 wire [7:0] gray_data ;
  21. 21 wire ycbcb_vsync;
  22. 22 wire ycbcbr_clken;
  23. 23 wire ycbcr_valid;
  24. 24
  25. 25 //*****************************************************
  26. 26 //** main code
  27. 27 //*****************************************************
  28. 28 //rgb转ycbcr模块
  29. 29 rgb2ycbcr u_rgb2ycbcr(
  30. 30 .clk (clk),
  31. 31 .rst_n (rst_n),
  32. 32
  33. 33 .rgb_vsync (pre_image_vsync),
  34. 34 .rgb_clken (pre_image_clken),
  35. 35 .rgb_valid (pre_data_valid),
  36. 36 .rgb_data (pre_image_data),
  37. 37
  38. 38
  39. 39 .ycbcb_vsync (ycbcb_vsync),
  40. 40 .ycbcbr_clken (ycbcbr_clken),
  41. 41 .ycbcr_valid (ycbcr_valid),
  42. 42 .gray_data (gray_data)
  43. 43 );
  44. 44
  45. 45 //二值化模块
  46. 46 binarization u_binarization(
  47. 47 .clk (clk),
  48. 48 .rst_n (rst_n),
  49. 49
  50. 50
  51. 51 .gray_vsync (ycbcb_vsync),
  52. 52 .gray_clken (ycbcbr_clken),
  53. 53 .gray_data_valid (ycbcr_valid),
  54. 54 .luminance (gray_data),
  55. 55
  56. 56
  57. 57 .binary_vsync (pos_image_vsync),
  58. 58 .binary_clken (pos_image_clken),
  59. 59 .binary_data_valid (pos_data_valid),
  60. 60 .binary_data (pos_image_data)
  61. 61 );
  62. 62
  63. 63 endmodule


有关“rgb2ycbcr”模块,大家可以参考OV5640摄像头灰度图显示实验,在此我们就不再介绍。
“binarization”模块的代码如下:

  1. 1 module binarization(
  2. 2 //module clock
  3. 3 input clk ,// 时钟信号
  4. 4 input rst_n ,// 复位信号(低有效)
  5. 5
  6. 6 //图像处理前的数据接口
  7. 7 input gray_vsync ,// vsync信号
  8. 8 input gray_clken ,// 时钟使能信号信号
  9. 9 input gray_data_valid ,// 数据有效信号
  10. 10 input [7:0] luminance ,
  11. 11
  12. 12 //图像处理后的数据接口
  13. 13 output binary_vsync ,// vsync信号
  14. 14 output binary_clken ,// 时钟使能信号
  15. 15 output binary_data_valid,// 数据有效信号
  16. 16 output [23:0] binary_data //
  17. 17 );
  18. 18
  19. 19 parameter THRESHOLD = 8'd80; //二值化的阈值
  20. 20
  21. 21 //reg define
  22. 22 reg gray_vsync_d;
  23. 23 reg gray_clken_d;
  24. 24 reg gray_data_valid_d;
  25. 25 reg monoc; //monochrome(1=白,0=黑)
  26. 26
  27. 27 //*****************************************************
  28. 28 //** main code
  29. 29 //*****************************************************
  30. 30
  31. 31 assign binary_vsync = gray_vsync_d;
  32. 32 assign binary_clken = gray_clken_d;
  33. 33 assign binary_data_valid = gray_data_valid_d;
  34. 34 assign binary_data = {24{monoc}};
  35. 35
  36. 36 //二值化
  37. 37 always @(posedge clk or negedge rst_n) begin
  38. 38 if(!rst_n)
  39. 39 monoc <= 1'b0;
  40. 40 else if(luminance > THRESHOLD) //比较图像灰度值与阈值的大小
  41. 41 monoc <= 1'b1;
  42. 42 else
  43. 43 monoc <= 1'b0;
  44. 44 end
  45. 45
  46. 46 //延时1拍以同步时钟信号
  47. 47 always@(posedge clk or negedge rst_n) begin
  48. 48 if(!rst_n) begin
  49. 49 gray_vsync_d <= 1'd0;
  50. 50 gray_clken_d <= 1'd0;
  51. 51 gray_data_valid_d <= 1'd0;
  52. 52 end
  53. 53 else begin
  54. 54 gray_vsync_d <= gray_vsync;
  55. 55 gray_clken_d <= gray_clken;
  56. 56 gray_data_valid_d <= gray_data_valid;
  57. 57 end
  58. 58 end
  59. 59
  60. 60 endmodule


在代码的第19行,我们定义了一个parameter类型的参数THRESHOLD,它是二值化过程中所设定的阈值。我们将灰度值与该阈值比较,用变量monoc寄存比较的结果。若灰度值大于该阈值则monoc为1,若小于阈值,则monoc为0,如代码第36到44行所示。理论上阈值可以是0到255中的任意值,但阈值过大,会提取多余的部分;而阈值过小,又会丢失所需的部分,因此阈值选取是影响实验的一个重要因素。
代码第46到58行,我们通过寄存操作对gray_vsync、gray_clken等信号作了一个时钟周期的延迟。这是因为在进行二值判定时消耗了一个时钟,因此相应的同步信号也要延迟一个时钟周期,以实现与数据的同步。
需要注意的是,代码中变量monoc的0和1表示的灰度与阈值比较的结果,而并不是像素的灰度值,我们需要根据monoc的值来给指定像素点的颜色。如代码第34行所示,binary_data 为24’h0表示黑色,为24’hff_ffff表示白色。
34 assign binary_data = {24{monoc}};
连线后的 Block Design 如下图所示:

41aceeb1b459c624339d146041fe2c0e.png

图 26.3.4 Block Design整体示意图


接下来验证当前设计。验证完成后弹出对话框提示没有错误或者关键警告,点击“OK”。如果验证结果
报出错误或者警告,则需要重新检查设计。
为工程添加的约束文件与“OV5640 摄像头 LCD 显示”完全相同,有关这一部分内容请读者参考“OV5640 摄像头 LCD 显示”实验。
最后在左侧 Flow Navigator 导航栏中找到 PROGRAM AND DEBUG,点击该选项中的“ Generate
Bitstream”,对设计进行综合、实现、并生成 Bitstream 文件。在生成 Bitstream 之后,在菜单栏中选择 File > Export > Export hardware 导出硬件, 并在弹出的对话框
中,勾选“Include bitstream”。然后在菜单栏选择 File > Launch SDK, 启动 SDK 软件。
26.4软件设计
本实验软件设计部分与“OV5640摄像头LCD显示”实验相同,在此处就不做赘述,有需要的朋友可以参考“OV5640摄像头LCD显示”实验软件设计部分。
26.5下载验证
编译完工程之后我们就可以开始下载程序了。将 OV5640 摄像头模块插在启明星 Zynq 开发板的“OLED/CAMERA”插座上,并将 LCD 的排线接头插入开发板上的 LCD 接线座。将下载器一端连电脑,
另一端与开发板上的 JTAG 端口连接,连接电源线并打开电源开关。
在 SDK 软件下方的 SDK Terminal 窗口中点击右上角的加号设置并连接串口。然后下载本次实验硬件
设计过程中所生成的 BIT 文件,来对 PL 进行配置。最后下载软件程序,下载完成后, 在下方的 SDK Terminal中可以看到应用程序打印的信息,如下图所示:

98ec68bdae249e2429c8dd010dc1095b.png

图 26.5.1 串口打印信息窗口


同时, RGB LCD 液晶屏上显示出 OV5640 摄像头采集的图像的灰度图,说明本次 OV5640 摄像头 RGB LCD 屏显示的实验在启明星 ZYQN 开发板上验证成功,如下图所示:

de5ed7d019175ba1d54c01cd0509975e.png

图 26.5.2 LCD屏显示结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/462017
推荐阅读
相关标签
  

闽ICP备14008679号