基于FPGA的幀差法仿真實(shí)現(xiàn)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
基于FPGA的幀差法仿真實(shí)現(xiàn)
一、幀差法的原理及應(yīng)用
幀差法就是幀間差分法,幀差法是最為常用的行動(dòng)目標(biāo)檢測(cè)措施之一,原理即是在圖像序列鄰接兩幀或三幀間基于像素做差分運(yùn)算來(lái)獲取。率先,將鄰接幀圖像對(duì)應(yīng)像素值相減獲得差分圖像,然后對(duì)差分圖像二值化,在環(huán)境亮度改變不大的情形下,對(duì)應(yīng)像素值改變小于預(yù)先確定的閾值時(shí),能夠感受這里為背景像素。假如圖像區(qū)域的像素值改變很大,能夠感受這是由于圖像中行動(dòng)物體引起的,將這些區(qū)域符號(hào)為前景像素,利用符號(hào)的像素區(qū)域能夠確定行動(dòng)目標(biāo)在圖像中的位置。由于鄰接兩幀間的工夫間隔極其短,用前一幀圖像作為目前幀的背景模型具有較好的實(shí)時(shí)性,其背景不聚集,且更新速度快、算法容易、計(jì)算量小。算法的不足在于對(duì)環(huán)境噪聲較為敏感,閾值的抉擇相當(dāng)關(guān)鍵,抉擇過(guò)低不足以壓抑圖像中的噪聲,過(guò)高則疏忽了圖像中有用的改變。對(duì)于比擬大的、顏色統(tǒng)一的行動(dòng)目標(biāo),有可能在目標(biāo)內(nèi)部發(fā)生抽象,無(wú)法全面地提取行動(dòng)目標(biāo)。多數(shù)應(yīng)用于選擇十字路口監(jiān)控錄像作為實(shí)驗(yàn)材料,檢測(cè)過(guò)往車輛動(dòng)態(tài),也能為后期機(jī)器識(shí)別打下基礎(chǔ)。
幀差法主要通過(guò)下面式子實(shí)現(xiàn),其中 x1 和 x2 分別為當(dāng)前幀和上一幀同一位置坐標(biāo)的像素點(diǎn)灰度值,T 為預(yù)設(shè)的參考分割閾值,y 為最終輸出的二值結(jié)果
二、幀差分法實(shí)現(xiàn)步驟
1、實(shí)驗(yàn)框圖
2、模塊介紹
a、 imread_framel :此模塊用于讀取事先準(zhǔn)備好需要進(jìn)行幀差法的兩幀或多幀圖片。
b、 Vga_crt:此模塊用于產(chǎn)生后續(xù)模塊所需時(shí)序。
c、 Hvcount :此模塊用于對(duì)后續(xù)模塊進(jìn)行時(shí)序同步。
d、 Framel_diff :此模塊用于幀差法的實(shí)現(xiàn)。
e、 Imwrite_fra :此模塊用于讀取幀差之后的結(jié)果。
三、幀差法的FPGA仿真實(shí)現(xiàn)
幀差法的原理比較簡(jiǎn)單,就是實(shí)時(shí)圖像的相鄰兩幀或者三幀做差,FPGA的實(shí)現(xiàn)的難點(diǎn)在于大部分FPGA的內(nèi)部存儲(chǔ)(BRAM)不足以存取一幅完整圖像的數(shù)據(jù),這時(shí)就需要借助外部的SDRAM或者DDR等存儲(chǔ)。
幀差法仿真源碼展示:
1. /******************************************************
2. // Project Name:Frame_Difference
3. //
4. // Author:Lee
5. // 微信公眾號(hào):FPGA開源工作室
6. *******************************************************/
7. `timescale 1ns / 1ps
8.
9. module Frame_Difference #(
10. parameter IW = 800,
11. parameter IH = 600,
12. parameter DW = 24
13. )(
14. input PixelClk,
15. input reset_n,
16. input [DW-1:0] i_rgb,
17. input i_hs,
18. input i_vs,
19. input i_de,
20. output [DW-1:0] o_rgb,
21. output o_hs,
22. output o_vs,
23. output o_de
24. );
25.
26.
27. reg we;
28. reg rd;
29. reg [20:0] waddr;//800*600
30. reg [20:0] raddr;
31. wire [DW-1:0] dout;
32. reg [DW-1:0] rgb_r;
33. reg [DW-1:0] dout_r;
34. reg hs_r0;
35. reg vs_r0;
36. reg de_r0;
37.
38. reg hs_r1;
39. reg vs_r1;
40. reg de_r1;
41.
42. reg hs_r2;
43. reg vs_r2;
44. reg de_r2;
45.
46. assign o_hs = hs_r2;
47. assign o_vs = vs_r2;
48. assign o_de = de_r2;
49. assign o_rgb = dout_r;
50. always @(posedge PixelClk )begin
51. rgb_r <= i_rgb;
52. hs_r0 <= i_hs;
53. vs_r0 <= i_vs;
54. de_r0 <= i_de;
55.
56. hs_r1 <= hs_r0 ;
57. vs_r1 <= vs_r0 ;
58. de_r1 <= de_r0 ;
59.
60. hs_r2 <= hs_r1 ;
61. vs_r2 <= vs_r1 ;
62. de_r2 <= de_r1 ;
63. end
64. always @(posedge PixelClk or negedge reset_n)begin
65. if(de_r1)
66. //dout_r <= dout - rgb_r; //Frame Difference
67. dout_r <= rgb_r - dout; //Frame Difference
68. else
69. dout_r <= 0;
70. end
71.
72. always @(posedge PixelClk or negedge reset_n)begin
73. if(!reset_n) begin
74. rd <= 0;
75. we <= 0;
76. raddr <= 0;
77. waddr <= 0;
78. end
79. else if(i_vs == 0) begin
80. rd <= 0;
81. we <= 0;
82. raddr <= 0;
83. waddr <= 0;
84. end
85. else if(i_de) begin
86. rd <= 1;
87. raddr <= raddr + 1;
88. we <= 1;
89. waddr <= waddr + 1;
90. end
91. else begin
92. rd <= 0;
93. we <= 0;
94. raddr <= raddr;
95. waddr <= waddr;
96. end
97. end
98.
99. Frame_Ram#(
100. .IW(IW),
101. .IH(IH),
102. .DW(DW)
103. )U_Frame_Ram(
104. .clk(PixelClk),
105. .reset_n(reset_n),
106. .we(we),
107. .rd(rd),
108. .waddr(waddr),//1920*1080
109. .raddr(raddr),
110. .din(i_rgb),
111. .dout(dout)
112. );
113.
114. endmodule
115.
116.
117. module Frame_Ram#(
118. parameter IW = 800,
119. parameter IH = 600,
120. parameter DW = 24
121. )(
122. input clk,
123. input reset_n,
124. input we,
125. input rd,
126. input [20:0] waddr,//800*600
127. input [20:0] raddr,
128. input [DW-1:0] din,
129. output [DW-1:0] dout
130. );
131.
132. //reg [DW-1:0] mem[0:IW*IH];
133. reg [DW-1:0] mem[IW*IH:0];
134.
135. reg [DW-1:0] rdata;
136. assign dout = rdata;
137.
138. integer n;
139. always @(posedge clk or negedge reset_n) begin
140. if(!reset_n) begin
141. for(n = 0; n
142. rdata <= 0;
143. end
144. else begin
145. if(rd) rdata <= mem[raddr]; else rdata <= 0;
146. if(we) mem[waddr] <= din;
147. end
148. end
149.
150. endmodule
代碼解釋:
幀差法代碼主要分為兩個(gè)模塊一個(gè)RAM用于存儲(chǔ)一幀圖像,Frame_Difference模塊用于實(shí)現(xiàn)兩幀之間點(diǎn)對(duì)點(diǎn)做差。
實(shí)驗(yàn)圖1
實(shí)驗(yàn)圖2
實(shí)驗(yàn)圖3
結(jié)果圖1
結(jié)果圖2
實(shí)驗(yàn)結(jié)果分析:
實(shí)驗(yàn)圖1為第一幀圖像,實(shí)驗(yàn)圖2為第二幀圖像,實(shí)驗(yàn)圖3為第三幀圖像,第二幀和第三幀做差如圖結(jié)果1所示,結(jié)果2為抓取結(jié)果1的位置。
在文章的末尾特別感謝網(wǎng)友遲茶枯對(duì)本文一二節(jié)內(nèi)容的貢獻(xiàn)。