直接上干货。今天咱们用Verilog在Basys3上实现一个能追着单色物体跑的视觉系统。别看乒乓球运动轨迹飘忽,抓住这几个关键点就能让FPGA死死咬住目标
·
基于FPGA的视觉跟踪系统,配合舵机云台跟踪单色物体,例如乒乓球。 vivado工程,基于Basys3板卡。 注意:不硬件部分。
先看图像处理流水线。OV7670摄像头出来的RGB565数据进FPGA后,首要任务是转换成HSV颜色空间。这里有个取巧的写法:
// RGB转HSV核心计算
always @(posedge clk) begin
max = (R > G) ? ((R > B) ? R : B) : ((G > B) ? G : B);
min = (R < G) ? ((R < B) ? R : B) : ((G < B) ? G : B);
delta = max - min;
// 色相计算部分
if(delta == 0) H <= 0;
else if(max == R) H <= ((G - B) * 60) / delta;
else if(max == G) H <= 120 + ((B - R) * 60) / delta;
else H <= 240 + ((R - G) * 60) / delta;
end
这个实现用了三级流水,实际跑在100MHz时钟下处理640x480图像毫无压力。注意除法运算这里直接用了IP核,自己写迭代除法器会严重拖慢时序。
颜色阈值处理阶段,重点在于动态调整。我们在Block Memory里存了六组阈值参数,通过板载按键实时切换:
reg [7:0] hue_threshold[5:0];
reg [2:0] preset_sel = 0;
always @(posedge clk) begin
if(hue > hue_threshold[preset_sel][7:4] &&
hue < hue_threshold[preset_sel][3:0])
binary_out <= 1'b1;
else
binary_out <= 1'b0;
end
调试时发现乒乓球的HSV值在特定光照下会漂移,所以预留了多个预设档位,现场调试时哪个档位锁定效果好用哪个。
物体追踪算法采用质心追踪法。每帧统计白色像素的坐标和:
reg [18:0] sum_x, sum_y; // 640*480=307200 < 2^19
reg [18:0] pixel_count;
always @(posedge vsync) begin
if(pixel_count != 0) begin
center_x <= sum_x / pixel_count;
center_y <= sum_y / pixel_count;
end
// 复位累加器
sum_x <= 0;
sum_y <= 0;
pixel_count <= 0;
end
这里有个坑:当目标移出画面时pixel_count可能为0,必须做除零保护。后来在除法器前加了条件判断,避免系统崩溃。
舵机控制用PWM波实现,重点在动态响应。根据目标偏移量计算舵机角度:
// 水平方向控制参数
reg signed [15:0] error_x;
reg [7:0] pwm_duty_x;
always @(posedge clk) begin
error_x = center_x - 320; // 屏幕中心320像素处
// 比例系数0.4,8位定点数计算
pwm_duty_x = 90 + (error_x * 10'sd102) >>> 8;
end
这个位移公式经过实测调校,系数102相当于0.4的定点数表示(102/256≈0.4)。右移8位替代除法运算,节省了大量逻辑资源。
最后来个联调技巧:在Vivado里设置ILA抓取图像处理中间信号,直接叠在VGA画面上显示阈值范围和质心位置,比用SignalTap逐帧分析效率高十倍。当看到红色标记框稳稳套住乱窜的乒乓球时,就知道这波稳了。
更多推荐


所有评论(0)