文章目录
该部分的目的是想要用verilog来实现汉明距离的计算。
汉明距离FPGA实现框架
1:进行异或运算;2:将每一个为1的进行相加,也就是对含1的个数进行统计。
汉明距离计算方法1
module Hamming(
input clk,
input rst_n,
input [7:0] din1,
input [7:0] din2,
output reg [7:0] Hamming,//八位数统计1的数量,只需要四位即可。
output reg [7:0] d_xor
);
integer i;
//两个二进制串进行异或运算
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
d_xor <= 'd0;
else
d_xor <= din1 ^ din2;
end
//统计异或运算得到的结果中1的个数
always @(*) begin
Hamming = 'd0;
for (i=0;i<8;i=i+1) begin
if (d_xor[i]==1'b1) begin
Hamming = Hamming + 1;
end
end
end
endmodule
仿真:
`timescale 1ns/1ns
module Hamming_tb;
reg clk;
reg rst_n;
reg [7:0] din1;
reg [7:0] din2;
wire [7:0] Hamming;
wire [7:0] d_xor;
Hamming inst_Hamming
(
.clk (clk),
.rst_n (rst_n),
.din1 (din1),
.din2 (din2),
.Hamming (Hamming),
.d_xor (d_xor)
);
initial clk = 0;
always #10 clk = ~clk;
initial begin
rst_n = 0;
#1;
rst_n = 1;
end
initial begin
din1 = 8'b0;
din2 = 8'b0;
#10;
din1 = 8'b0001_1101;
din2 = 8'b0100_1001;
#20;
din1 = 8'b1101_1101;
din2 = 8'b1101_1001;
#20;
din1 = 8'b1101_1001;
din2 = 8'b0001_1001;
#20;
din1 = 8'b1100_1001; //两个二进制串对应位都不相同
din2 = 8'b0011_0110;
#20;
$stop;
end
endmodule
汉明距离计算方法2
加入了按位与的计算,其实没必要
module Hamming(
input clk,
input rst_n,
input [7:0] din1,
input [7:0] din2,
output reg [7:0] Hamming,
output reg [7:0] d_xor,
output reg [7:0] and_xor
);
integer i;
//两个二进制串进行异或运算
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
d_xor <= 'd0;
else
d_xor <= din1 ^ din2;
end
//统计异或运算得到的结果中1的个数
//第一步:逐位进行与运算
always @(*) begin
and_xor = 'd0;
for (i=0;i<8;i=i+1) begin
and_xor[i] = &d_xor[i];
end
end
//求和
always @(*) begin
Hamming = 'd0;
for (i=0;i<8;i=i+1) begin
if(and_xor[i] == 1 )begin
Hamming = Hamming +1 ;
end
end
end
endmodule
tb测试:
`timescale 1ns/1ns
module Hamming_tb;
reg clk;
reg rst_n;
reg [7:0] din1;
reg [7:0] din2;
wire [7:0] Hamming;
wire [7:0] d_xor;
wire [7:0] and_xor;
Hamming inst_Hamming
(
.clk (clk),
.rst_n (rst_n),
.din1 (din1),
.din2 (din2),
.Hamming (Hamming),
.and_xor(and_xor),
.d_xor (d_xor)
);
initial clk = 0;
always #10 clk = ~clk;
initial begin
rst_n = 0;
#1;
rst_n = 1;
end
initial begin
din1 = 8'b0;
din2 = 8'b0;
#10;
din1 = 8'b0001_1101;
din2 = 8'b0100_1001;
#20;
din1 = 8'b1101_1101;
din2 = 8'b1101_1001;
#20;
din1 = 8'b1101_1001;
din2 = 8'b0001_1001;
#20;
din1 = 8'b1100_1001; //两个二进制串对应位都不相同
din2 = 8'b0011_0110;
#20;
$stop;
end
endmodule
汉明距离计算方法3
module Hamming(
input clk,
input [7:0] din1,
input [7:0] din2,
input de1,
input de2,
output reg Ccen_Hamming_de,
output reg [7:0] Hamming,
output [7:0] d_xor
);
wire de;
assign de = de1 & de2;
//两个二进制串进行异或运算
assign d_xor = de ? (din1 ^ din2) : 8'd0;
//统计异或运算得到的结果中1的个数
always@(posedge clk)begin
Hamming <= d_xor[0]+d_xor[1]+d_xor[2]+d_xor[3]+d_xor[4]+d_xor[5]+d_xor[6]+d_xor[7];
end
always@(posedge clk)begin
Ccen_Hamming_de <= de;
end
endmodule
`timescale 1ns/1ns
module Hamming_tb;
reg clk;
reg de1;
reg de2;
reg [7:0] din1;
reg [7:0] din2;
wire [7:0] Hamming;
wire [7:0] d_xor;
wire Ccen_Hamming_de;
Hamming inst_Hamming
(
.clk (clk),
.de1 (de1),
.de2 (de2),
.din1 (din1),
.din2 (din2),
.Hamming (Hamming),
.Ccen_Hamming_de(Ccen_Hamming_de),
.d_xor (d_xor)
);
initial clk = 1;
always #10 clk = ~ clk;
initial begin
de1 = 0;
de2 = 0;
#10;
de1 = 1;
de2 = 1;
#60;
de1 = 0;
de2 = 0;
end
initial begin
din1 = 8'b0;
din2 = 8'b0;
#10;
din1 = 8'b0001_1101;
din2 = 8'b0100_1001;
#20;
din1 = 8'b1101_1101;
din2 = 8'b1101_1001;
#20;
din1 = 8'b1101_1001;
din2 = 8'b0001_1001;
#20;
din1 = 8'b1100_1001; //两个二进制串对应位都不相同
din2 = 8'b0011_0110;
#20;
din1 = 8'b0000_1001; //两个二进制串对应位都不相同
din2 = 8'b0011_0110;
#40;
$stop;
end
endmodule
汉明距离计算的实际应用
下面展现从左右摄像头进来的数据,分别进行滤波操作,也就是窗口滑动。
由于存在视差,那么说明进行census变换的时候基准是不一样的,但是基准的不同,只不是比较的时候改变了像素,比如之前中心像素为基准f22.可能现在变成了f12为基准,那么窗口内每一个像素和f12比较即可,最终得到二进制串,也成为Census变换结果。
得到Census变换结果后,进行汉明距离的计算,从而得到匹配代价。
、
如下是总体的图,先生成窗口,然后遍历图像,遍历左图进行census变换,得到一个二进制串。
与此同时,同样大小的窗口遍历右图,右图的基准像素和左图不同,存在一个视差d,但最终也会得到一个二进制串。
得到这两个二进制串之后即可送入到汉明距离计算模式,最终得到汉明距离值。
census变换模块
可看到其本质就是比较,窗口内的每一个像素,与基准像素进行比较。3*3的窗口,因此需要比较8次。
最终将八个01的数进行位拼接。
至此 ,相当于我们完成了汉明距离的计算——也就是匹配代价。
注意上面只是左图中的census变换值和对应右图的结果进行运算,但实际的我们需要将左图的census变换值与右图的每一个像素点,或者说改进之后,与右图中该极线上的每一个点进行比较。
既然是想要只比较同一行的滤波值,那么我们可以将右图延迟一行,相当于缓存了一行,即可实现这种比较。
Census变换改进——不依赖中心像素
也就是进行比较的时候我们将某点像素值,与平均灰度值和下一点的灰度值进行比较。
代价聚合
后续要研究d视差怎么计算的——WAT
视差计算WAT
赢者通吃算法WAT————找最小值