-
Notifications
You must be signed in to change notification settings - Fork 12
/
centroid_2cam.v
307 lines (276 loc) · 12 KB
/
centroid_2cam.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
//------------------------------------------------------------------------------
// Felipe Machado Sanchez
// Area de Tecnologia Electronica
// Universidad Rey Juan Carlos
// https://github.com/felipe-m
//
// centroid_2cam.v
// - Receives the x histogram of a merged image. It comes from 2 cameras
// the histogram may come from left, right, o hypotetical middle camera
// This histogram is the image divided along the x axis (columns) in 8 bins
// and it indicates how many pixels in each bin has passed the color filter
// - Ouputs the centroid and also the proximity, which is calculated just
// counting pixels that have passed the filter
//
// Camera bins of the histogram:
//
// LEFT CAM RIGHT CAM
// 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
// 0 1 2 3 4 5 6 7 -> MID CAM
// outputs:
// ----------
// centroid:
//
// 0123 4567 :bit number
// ----------
// 0001 1000 : centered
//
// 0001 0000 : slightly to the left
// 0010 0000 : to the left
// 0100 0000 : more to the left
// 1000 0000 : to the left most
//
// 0000 1000 : slightly to the right
// 0000 0100 : to the right
// 0000 0010 : more to the right
// 0000 0001 : to the right most
//
// new_centroid
//
//
module centroid_2cam
# (parameter
// VGA
//c_img_cols = 640, // 10 bits
//c_img_rows = 480, // 9 bits
//c_img_pxls = c_img_cols * c_img_rows,
//c_nb_line_pxls = 10, // log2i(c_img_cols-1) + 1;
// c_nb_img_pxls = log2i(c_img_pxls-1) + 1
//c_nb_img_pxls = 19, //640*480=307,200 -> 2^19=524,288
// QQVGA
c_img_cols = 160, // 8 bits
c_img_rows = 120, // 7 bits
//c_img_pxls = c_img_cols * c_img_rows,
//c_nb_img_pxls = $clog2(c_img_pxls), // 15 -> 160*120=19,200 -> 2^15
// QQVGA /2
//c_img_cols = 80, // 7 bits
//c_img_rows = 60, // 6 bits
//c_img_pxls = c_img_cols * c_img_rows,
//c_nb_img_pxls = $clog2(c_img_pxls), // 13, //80*60=4800 -> 2^13
// number of bits of the image colums and rows
c_nb_cols = $clog2(c_img_cols),
c_nb_rows = $clog2(c_img_rows),
// inner frame size
c_inframe_cols = 128, // 7 bits (0 to 127) taking out 32, 16 each side
c_inframe_rows = 104, // 7 bits (0 to 107) taking out 16, 8 each side
// total pixels in the inner frame
c_inframe_pxls = c_inframe_cols * c_inframe_rows, // 128x104 = 13312
// number of bits for the number of total pixels in the inner frame
c_nb_inframe_pxls = $clog2(c_inframe_pxls), // = 14
// histogram
// number of bins (buckets)
c_hist_bins = 8, // 7:0
// number of bits needed for the histogram bins: 8 bins -> 3 bits
//c_nb_hist_bins = $clog2(c_hist_bins), // 3 bits
// since we have 104 rows and 8 column in each bin
// for each bin 832 (104 x 8) is the max number: 10 bits
c_nb_hist_val = $clog2(c_inframe_rows *(c_inframe_cols/c_hist_bins)),//=10
// centroid has 8 bits, it is decoded, so its not a number
c_nb_centroid = 8,
// proximity calculation, for now just 3 bits 0 to 7 (0: far, 7:close)
c_nb_prox = 3,
// minimum number to consider an image detected and not being noise
// change this value
c_min_colorpxls = 128 //having 13312 pxls, at least 128 seems reasonable
)
(
input rst, //reset, active high
input clk, //fpga clock
input new_frame_proc_i, // a new frame has been processed
input left_cam_i, // indicates from which camera comes the image
input mid_cam_i,
input rght_cam_i,
// cannot have a port as an array. These are the 8 bins of the histogram
// total number of pixels that are above the threshold
input [c_nb_inframe_pxls-1:0] colorpxls_i,
//input [c_nb_hist_val-1:0] histogram_i [c_hist_bins-1:0],
input [c_nb_hist_val-1:0] colorpxls_bin0_i,
input [c_nb_hist_val-1:0] colorpxls_bin1_i,
input [c_nb_hist_val-1:0] colorpxls_bin2_i,
input [c_nb_hist_val-1:0] colorpxls_bin3_i,
input [c_nb_hist_val-1:0] colorpxls_bin4_i,
input [c_nb_hist_val-1:0] colorpxls_bin5_i,
input [c_nb_hist_val-1:0] colorpxls_bin6_i,
input [c_nb_hist_val-1:0] colorpxls_bin7_i,
// total number of pixels that are above the threshold on the left side
// bins 0 to 3
input [c_nb_inframe_pxls-2:0] colorpxls_left_i,
input [c_nb_inframe_pxls-2:0] colorpxls_rght_i,
// total number of pixels that are above the threshold on the bins 0to2
input [c_nb_inframe_pxls-2:0] colorpxls_bin012_i, // leftmost bins
input [c_nb_inframe_pxls-2:0] colorpxls_bin567_i, // rightmost bins 5to7
// total number of pixels that are above the threshold on the bins 0,1
input [c_nb_inframe_pxls-2:0] colorpxls_bin01_i, // leftmost bins
input [c_nb_inframe_pxls-2:0] colorpxls_bin67_i, // rightmost bins 6to7
output reg [c_nb_centroid-1:0] centroid_o,
output reg new_centroid_o, // new centroid available, one pulse
// proximity: how clos is the object 7: close ; 0: far
output reg [c_nb_prox-1:0] proximity_o //
);
// total color pixels divided by 2
wire [c_nb_inframe_pxls-2:0] colorpxls_half;
// result of the division of the total number of threshold pixels
// initially, divided by 16, could be 8
wire [c_nb_inframe_pxls-2:0] colorpxls_div;
//proximity, combinational, value not valid until reaching the end of the frame
reg [c_nb_prox-1:0] proximity_cmb; //proximity, combinational, so
// temporal calculation of the centroid
reg [c_nb_centroid-1:0] centroid_tmp;
reg [c_nb_prox-1:0] proximity_tmp; // proximity
// indicates if there are more threshold pixels on the left half of the
// inner frame
wire left;
// indicates the absolute difference (positive) between the pixels on the
// right and left
wire [c_nb_inframe_pxls-2:0] absdif_lft_rght;
wire bin0_gth, bin01_gth, bin012_gth, bin7_gth, bin67_gth, bin567_gth;
assign left = (colorpxls_left_i > colorpxls_rght_i) ? 1'b1 : 1'b0;
assign absdif_lft_rght = (left == 1'b1) ? (colorpxls_left_i - colorpxls_rght_i) :
(colorpxls_rght_i - colorpxls_left_i);
// divided by 2 -> 1 bit
assign colorpxls_half = colorpxls_i[c_nb_inframe_pxls-1:1];
// divided by 16 -> 4 bits
assign colorpxls_div = {4'b0 , colorpxls_i[c_nb_inframe_pxls-1:4]};
// comparators of bins to reuse them in all the comparisons:
// bins: 0 1 2 3 4 5 6 7
// gth: greather than the other half
assign bin0_gth = (colorpxls_bin0_i >= colorpxls_half) ? 1'b1 : 1'b0;
assign bin01_gth = (colorpxls_bin01_i >= colorpxls_half) ? 1'b1 : 1'b0;
assign bin012_gth = (colorpxls_bin012_i >= colorpxls_half) ? 1'b1 : 1'b0;
assign bin7_gth = (colorpxls_bin7_i >= colorpxls_half) ? 1'b1 : 1'b0;
assign bin67_gth = (colorpxls_bin67_i >= colorpxls_half) ? 1'b1 : 1'b0;
assign bin567_gth = (colorpxls_bin567_i >= colorpxls_half) ? 1'b1 : 1'b0;
always @(*)
begin
centroid_tmp = 0; // default assignment
//first if the difference between the colored pixels on de left is less than
// 16 percent (maybe it could be 8%)
if (colorpxls_i <= c_min_colorpxls) // not enough color pixels detected
centroid_tmp = 0;
else if (mid_cam_i) begin
if (absdif_lft_rght < colorpxls_div) // consider in the middle
centroid_tmp[4:3] = 2'b11; // 0001 1000
//centroid_tmp = 8'b00011000;
else if (left) begin // more threshold pixels on the left
// start checking from the edges
if (bin0_gth) // (colorpxls_bin0_i >= colorpxls_half)
centroid_tmp[0] = 1'b1; // 1000 0000
else if (bin01_gth) // (colorpxls_bin01_i >= colorpxls_half)
centroid_tmp[1] = 1'b1; // 0100 0000
else if (bin012_gth) // (colorpxls_bin012_i >= colorpxls_half)
centroid_tmp[2] = 1'b1; // 0010 0000
else // if (colorpxls_left_i > colorpxls_half) -- no other option
centroid_tmp[3] = 1'b1; // 0001 0000
end
else begin // more pixels on the right side
// start checking from the edges
if (bin7_gth) // (colorpxls_bin7_i >= colorpxls_half)
centroid_tmp[7] = 1'b1; // 0000 0001
else if (bin67_gth) // (colorpxls_bin67_i >= colorpxls_half)
centroid_tmp[6] = 1'b1; // 0000 0010
else if (bin567_gth) // (colorpxls_bin567_i >= colorpxls_half)
centroid_tmp[5] = 1'b1; // 0000 0100
else // if (colorpxls_rght_i > colorpxls_half) -- no other option
centroid_tmp[4] = 1'b1; // 0000 1000
end
end
else if (left_cam_i) begin
// LEFT CAM RIGHT CAM
// 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
// 0 1 2 3 4 5 6 7 -> MID CAM
if (bin7_gth)
centroid_tmp[3] = 1'b1; // 0001 0000
else if (bin67_gth)
centroid_tmp[2] = 1'b1; // 0010 0000
else if (bin567_gth)
centroid_tmp[1] = 1'b1; // 0100 0000
else
// In this first version, we consider the left part all the same
centroid_tmp[0] = 1'b1; // 1000 0000
end
else if (rght_cam_i) begin
// LEFT CAM RIGHT CAM
// 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
// 0 1 2 3 4 5 6 7 -> MID CAM
if (bin0_gth)
centroid_tmp[4] = 1'b1; // 0000 1000
else if (bin01_gth)
centroid_tmp[5] = 1'b1; // 0000 0100
else if (bin012_gth)
centroid_tmp[6] = 1'b1; // 0000 0010
else
// In this first version, we consider the right part all the same
centroid_tmp[7] = 1'b1; // 0000 0001
end
end
// proximity measurement (color pixel count
// making the assumption that all pixels are together and that there is no
// noise. In the future we will consider this
// only considering pixles in the inner frame
// distance: how many pixels are detected
// since in the inner frame there are 3072 pixels (64x48) -> 12 bits
// (c_nb_inframe_pxls),
// lets say that we are too close if we have 2048 or more, that is,
// bit 12 is one
// Total : 3072
// >= 2048 : 2/3 - bits: 11 ='1' 7 -> Max, very close
// >= 1536 = 1024+512 : 1/2 - bits: 10:9 ='11' 7 -> Max, very close
// >= 1024 : 1/3 - bits: 10 ='1' 6
// >= 512 : 1/6 - bits: 9 ='1' 5
// >= 256 : 1/12- bits: 8 ='1' 4
// >= 128 : 1/24- bits: 7 ='1' 3
// >= 64 : 1/48- bits: 6 ='1' 2
// >= 32 : 1/96- bits: 5 ='1' 1
// < 32 0 -> Min
always @(*)
begin
if (colorpxls_i[c_nb_inframe_pxls-2] == 1'b1) begin // bit 10
if (colorpxls_i[c_nb_inframe_pxls-3] == 1'b1) begin // bit 9
proximity_tmp <= 3'd7; // bits 10:9 too close, max proximity >=1536 : 1/2
end
else
proximity_tmp <= 3'd6; // bit 10 too close, max proximity >=1024 : 1/3
end
else if (colorpxls_i[c_nb_inframe_pxls-3] == 1'b1) begin // bit 9
proximity_tmp <= 3'd5; // 6: bit 9 >= 512 - 1/6
end
else if (colorpxls_i[c_nb_inframe_pxls-4] == 1'b1) begin // bit 8
proximity_tmp <= 3'd4; // 5: bit 8 >= 256 - 1/12
end
else if (colorpxls_i[c_nb_inframe_pxls-5] == 1'b1) begin // bit 7
proximity_tmp <= 3'd3; // 4: bit 7 >= 128 - 1/24
end
else if (colorpxls_i[c_nb_inframe_pxls-6] == 1'b1) begin // bit 6
proximity_tmp <= 3'd2; // 3: bit 6 >= 64 - 1/48
end
else if (colorpxls_i[c_nb_inframe_pxls-7] == 1'b1) begin // bit 5
proximity_tmp <= 3'd1; // bit 5 >= 32 - 1/96
end
else
proximity_tmp <= 3'd0; // < 32
end
// register the outputs
always @ (posedge clk, posedge rst)
begin
if (rst) begin
new_centroid_o <= 1'b0;
centroid_o <= 0;
proximity_o <= 0;
end
else begin
new_centroid_o <= new_frame_proc_i;
centroid_o <= centroid_tmp;
proximity_o <= proximity_tmp;
end
end
endmodule