请选择 进入手机版 | 继续访问电脑版
[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_图像入门连载-25FPGA 实现基于帧差法的目标检测

文档创建者:FPGA课程
浏览次数:179
最后更新:2024-10-22
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-FPGA部分 » 2_FPGA实验篇(仅旗舰) » 8-FPGA图像入门
本帖最后由 FPGA课程 于 2024-10-22 19:58 编辑

​软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!



1 图像帧差法的目标检测算法简介
图像帧差法是常用的运动目标检测的方法之一,其原理是在视频图像序列中相邻两帧或三帧间采用基于帧图像 的像素差分得到图像中的运动区域。
首先,将相邻帧图像对应像素相减得到差分图像,然后进行图像二值化,在环境亮度变化不大的情况下,如果 对应像素变化小于阈值时,那么就为背景像素。如果图像区域的像素变化很大,认为这是图像中运动物体引起的, 将这些区域标记为前景像素,利用标记的像素区域就可以确定运动目标在图像中的位置。由于相邻两帧间的时间短,用前一帧图像作为当前帧的背景有较好的实时性,更新速度快、算法简单、计算量 小。同时算法不足是对环境噪声十分敏感,阈值的选择很关键,选择小了不能抑制图像中的噪声,高了则忽略了图 像中的变化。
9289b96ef58c4f959171c8f4fdadba4f.jpg
2 设计分析
2.1Verilog 代码分析
  1. //帧差分核心源代码:

  2. parameter THRESHOLD = 70;// 20~100

  3. reg                   i_hsyn_d0; reg                   i_vsyn_d0; reg                   i_de_d0;
  4. reg [7:0]  data_d0;

  5. reg           frame_diff_begin; reg [2:0]      frame_cnt;

  6. always@(posedge i_clk) begin
  7. i_hsyn_d0 <= i_hsyn; i_vsyn_d0 <= i_vsyn; i_de_d0      <= i_de;
  8. data_d0      <= i_data_0[7:0];
  9. end

  10. always@(posedge i_clk ornegedge i_rst_n) begin
  11. if(!i_rst_n) begin
  12. frame_cnt <= 0; end
  13. else if(~i_vsyn & i_vsyn_d0) begin
  14. if(frame_cnt == 5)
  15. frame_cnt <= 5;
  16. else
  17. frame_cnt <= frame_cnt + 1;
  18. end end

  19. always@(posedge i_clk ornegedge i_rst_n) begin
  20. if(!i_rst_n) begin
  21. frame_diff_begin <= 0;
  22. end
  23. else if(frame_cnt == 5) begin
  24. frame_diff_begin <= 1; end
  25. end

  26. always@(posedge i_clk ornegedge i_rst_n) begin
  27. if(!i_rst_n) begin
  28. o_data <= 8'h00; end
  29. else if(frame_diff_begin == 1 && i_de_d0 == 1) begin
  30. if(i_data_0[7:0] <= i_data_1[7:0]) begin
  31. if(i_data_ 1[7:0] - i_data_0[7:0] >= THRESHOLD)
  32. o_data <= 8'hff; else
  33. o_data <= 8'h00;
  34. end    else    begin
  35. if(i_data_0[7:0] - i_data_ 1[7:0] >= THRESHOLD)
  36. o_data <= 8'hff; else
  37. o_data <= 8'h00;
  38. end end
  39. end

  40. always@(posedge i_clk ) begin
  41. o_hs    <= i_hsyn_d0;
  42. o_vs    <= i_vsyn_d0;
  43. o_de    <= i_de_d0    ;
  44. end

  45. 选取框的代码:
  46. always@(posedge i_clk ) begin
  47. i_vsyn_d <= i_vsyn; end
  48. //显示区域行计数
  49. always@(posedge i_clk ornegedge i_rst_n) begin
  50. if(!i_rst_n) begin
  51. h_cnt <= 11'd0; end
  52. else if(i_de) begin
  53. if(h_cnt == H_ACTIVE - 1'b1) h_cnt <= 11'd0;
  54. else
  55. h_cnt <= h_cnt + 11'd1;
  56. end end
  57. //显示区域场计数
  58. always@(posedge i_clk ornegedge i_rst_n) begin
  59. if(!i_rst_n) begin
  60. v_cnt <= 11'd0; end
  61. else if(h_cnt == H_ACTIVE - 1'b1) begin
  62. if(v_cnt == V_ACTIVE - 1'b1) v_cnt <= 11'd0;
  63. else
  64. v_cnt <= v_cnt + 11'd1;
  65. end end
  66. //查找 H 最小值
  67. always@(posedge i_clk ornegedge i_rst_n) begin
  68. if(!i_rst_n) begin
  69. h_min    <= H_ACTIVE;
  70. end
  71. else if(~i_vsyn_d & i_vsyn) begin
  72. h_min    <= H_ACTIVE;
  73. end
  74. else if(i_data == 8'hff && h_min > h_cnt) begin
  75. h_min    <= h_cnt;
  76. end
  77. end

  78. //查找 H 最大值
  79. always@(posedge i_clk ornegedge i_rst_n) begin
  80. if(!i_rst_n) begin
  81. h_max    <= 8'h00;
  82. end
  83. else if(~i_vsyn_d & i_vsyn) begin
  84. h_max    <= 8'h00;
  85. end
  86. else if(i_data == 8'hff && h_max < h_cnt) begin
  87. h_max    <= h_cnt;
  88. end end
  89. //查找 V 最小值
  90. always@(posedge i_clk ornegedge i_rst_n) begin
  91. if(!i_rst_n) begin
  92. v_min    <= V_ACTIVE;
  93. end
  94. else if(~i_vsyn_d & i_vsyn) begin
  95. v_min    <= V_ACTIVE;
  96. end
  97. else if(i_data == 8'hff && v_min > v_cnt) begin
  98. v_min    <= v_cnt;
  99. end end
  100. //查找 V 最大值
  101. always@(posedge i_clk ornegedge i_rst_n) begin
  102. if(!i_rst_n) begin
  103. v_max    <= 8'h00;
  104. end
  105. else if(~i_vsyn_d & i_vsyn) begin
  106. v_max    <= 8'h00;
  107. end
  108. else if(i_data == 8'hff && v_max < v_cnt) begin
  109. v_max    <= v_cnt;
  110. end end

  111. always@(posedge i_clk ornegedge i_rst_n) begin
  112. if(!i_rst_n) begin
  113. h_min_d <= 'd0;  h_max_d <= 'd0; v_min_d <= 'd0;  v_max_d <= 'd0;
  114. end
  115. else if(~i_vsyn & i_vsyn_d) begin
  116. h_min_d <= h_min;  h_max_d <= h_max; v_min_d <= v_min;  v_max_d <= v_max;
  117. end end
  118. //显示区域行计数
  119. always@(posedge i_clk ornegedge i_rst_n) begin
  120. if(!i_rst_n) begin
  121. ori  h  cnt <= 11'd0; end
  122. else if(i_de_original) begin
  123. if(ori  h  cnt == H_ACTIVE - 1'b1) ori  h  cnt <= 11'd0;
  124. else
  125. ori  h  cnt <= ori  h  cnt + 11'd1;
  126. end end
  127. //显示区域场计数
  128. always@(posedge i_clk ornegedge i_rst_n) begin
  129. if(!i_rst_n) begin
  130. ori  v  cnt <= 11'd0; end
  131. else if(ori  h  cnt == H_ACTIVE - 1'b1) begin
  132. if(ori  v  cnt == V_ACTIVE - 1'b1) ori  v  cnt <= 11'd0;
  133. else
  134. ori  v  cnt <= ori  v  cnt + 11'd1;
  135. end end

  136. always@(posedge i_clk ornegedge i_rst_n) begin
  137. if(!i_rst_n) begin
  138. o_r <= 'd0;  o_g <= 'd0; o_b <= 'd0;
  139. end
  140. else  if(((ori  h  cnt  ==  h_min_d  ||  ori  h  cnt  ==  h_max_d  )  &&  ori  v  cnt  >=  v_min_d  &&  ori  v  cnt  <= v_max_d)||
  141. ((ori  v  cnt  ==  v_min_d  ||  ori  v  cnt  ==  v_max_d  )  &&  ori  h  cnt  >=  h_min_d  &&  ori  h  cnt  <=
  142. h_max_d))
  143. begin
  144. o_r <= R_VALUE;  o_g <= G_VALUE; o_b <= B_VALUE;
  145. end    else    begin
  146. o_r <= i  r  original;  o_g <= i  g  original; o_b <= i  b  original;
  147. end end
复制代码

2.2 工程结构分析
我们将图像算法的模块做成 IP 后,在vivado 中进行工程的搭建,工程结构如图所示:
2a661fea1f0e4a198316524cf3805bbc.jpg
3 搭建 Vitis-sdk 工程
创建 soc_base  sdk  platform  和 APP  工程的过程不再重复,可以阅读 3-3-01_sdk_base_app。以下给出创建好 soc_base sdk platform 的截图和对应工程 APP 的截图。
3.1 创建 SDK Platform 工程
7bcdc5bcb7ce42fc9e1c0613c98432e2.jpg

3.2SDKAPP工程

43484753f81b4f789f9cc7fc5a4b0c43.jpg

4 硬件连接
硬件连接如图所示:
89b93b2e3da44588b0c7f8aa1d197940.jpg

5 上板实验结果
实验结果如图所示:
df0153761640452898d52366f4b6f0a3.jpg

173dcedc42b846b4b66d9516df56fe23.jpg




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则