40 #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP ||\ 41 CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE 50 using namespace Linux;
53 uint32_t max_flow_pixel,
54 float bottom_flow_feature_threshold,
55 float bottom_flow_value_threshold) :
57 _bytesperline(bytesperline),
58 _search_size(max_flow_pixel),
59 _bottom_flow_feature_threshold(bottom_flow_feature_threshold),
60 _bottom_flow_value_threshold(bottom_flow_value_threshold)
87 static inline uint32_t
compute_diff(uint8_t *image, uint16_t offx, uint16_t offy,
88 uint16_t row_size, uint8_t window_size)
92 uint16_t
off = (offy + 2) * row_size + (offx + 2);
96 for (i = 0; i < window_size; i++) {
100 acc += abs(image[off + i] - image[off + i + row_size]);
101 acc += abs(image[off + i + row_size] - image[off + i + 2 * row_size]);
102 acc += abs(image[off + i + 2 * row_size] -
103 image[off + i + 3 * row_size]);
108 acc += abs(image[off + row_size * i] - image[off + row_size * i + 1]);
109 acc += abs(image[off + row_size * i + 1] -
110 image[off + row_size * i + 2]);
111 acc += abs(image[off + row_size * i + 2] -
112 image[off + row_size * i + 3]);
128 static inline uint32_t
compute_sad(uint8_t *image1, uint8_t *image2,
129 uint16_t off1x, uint16_t off1y,
130 uint16_t off2x, uint16_t off2y,
131 uint16_t row_size, uint16_t window_size)
136 uint16_t off1 = off1y * row_size + off1x;
137 uint16_t off2 = off2y * row_size + off2x;
141 for (i = 0; i < window_size; i++) {
142 for (j = 0; j < window_size; j++) {
143 acc += abs(image1[off1 + i + j*row_size] -
144 image2[off2 + i + j*row_size]);
162 uint16_t off1x, uint16_t off1y,
163 uint16_t off2x, uint16_t off2y,
164 uint32_t *acc, uint16_t row_size,
165 uint16_t window_size)
168 uint16_t off1 = off1y * row_size + off1x;
169 uint16_t off2 = off2y * row_size + off2x;
173 memset(acc, 0, window_size *
sizeof(uint32_t));
175 for (i = 0; i < window_size; i++) {
176 for (j = 0; j < window_size; j++) {
193 sub[0] = (image2[off2 + i + j*row_size] +
194 image2[off2 + i + 1 + j*row_size])/2;
196 sub[1] = (image2[off2 + i + j*row_size] +
197 image2[off2 + i + 1 + j*row_size] +
198 image2[off2 + i + (j+1)*row_size] +
199 image2[off2 + i + 1 + (j+1)*row_size])/4;
201 sub[2] = (image2[off2 + i + j*row_size] +
202 image2[off2 + i + 1 + (j+1)*row_size])/2;
204 sub[3] = (image2[off2 + i + j*row_size] +
205 image2[off2 + i - 1 + j*row_size] +
206 image2[off2 + i - 1 + (j+1)*row_size] +
207 image2[off2 + i + (j+1)*row_size])/4;
209 sub[4] = (image2[off2 + i + j*row_size] +
210 image2[off2 + i - 1 + (j+1)*row_size])/2;
212 sub[5] = (image2[off2 + i + j*row_size] +
213 image2[off2 + i - 1 + j*row_size] +
214 image2[off2 + i - 1 + (j-1)*row_size] +
215 image2[off2 + i + (j-1)*row_size])/4;
217 sub[6] = (image2[off2 + i + j*row_size] +
218 image2[off2 + i + (j-1)*row_size])/2;
220 sub[7] = (image2[off2 + i + j*row_size] +
221 image2[off2 + i + 1 + j*row_size] +
222 image2[off2 + i + (j-1)*row_size] +
223 image2[off2 + i + 1 + (j-1)*row_size])/4;
225 for (k = 0; k < 8; k++) {
226 acc[k] += abs(image1[off1 + i + j*row_size] - sub[k]);
235 uint32_t delta_time,
float *pixel_flow_x,
246 float meanflowx = 0.0f;
247 float meanflowy = 0.0f;
248 uint16_t meancount = 0;
249 float histflowx = 0.0f;
250 float histflowy = 0.0f;
263 uint32_t dist = 0xFFFFFFFF;
268 for (jj = winmin; jj <= winmax; jj++) {
269 for (ii = winmin; ii <= winmax; ii++) {
270 uint32_t temp_dist =
compute_sad(image1, image2, i, j,
272 (uint16_t)_bytesperline,
274 if (temp_dist < dist) {
284 meanflowx += (float)sumx;
285 meanflowy += (float) sumy;
288 acc, (uint16_t) _bytesperline,
290 uint32_t mindist = dist;
293 if (acc[k] < mindist) {
299 dirsx[meancount] = sumx;
300 dirsy[meancount] = sumy;
301 subdirs[meancount] = mindir;
309 meanflowx /= meancount;
310 meanflowy /= meancount;
313 uint32_t meancount_x = 0;
314 uint32_t meancount_y = 0;
316 for (uint16_t h = 0; h < meancount; h++) {
317 float subdirx = 0.0f;
318 if (subdirs[h] == 0 || subdirs[h] == 1 || subdirs[h] == 7) {
321 if (subdirs[h] == 3 || subdirs[h] == 4 || subdirs[h] == 5) {
324 histflowx += (float)dirsx[h] + subdirx;
327 float subdiry = 0.0f;
328 if (subdirs[h] == 5 || subdirs[h] == 6 || subdirs[h] == 7) {
331 if (subdirs[h] == 1 || subdirs[h] == 2 || subdirs[h] == 3) {
334 histflowy += (float)dirsy[h] + subdiry;
338 histflowx /= meancount_x;
339 histflowy /= meancount_y;
341 *pixel_flow_x = histflowx;
342 *pixel_flow_y = histflowy;
344 *pixel_flow_x = 0.0f;
345 *pixel_flow_y = 0.0f;
float _bottom_flow_feature_threshold
Flow_PX4(uint32_t width, uint32_t bytesperline, uint32_t max_flow_pixel, float bottom_flow_feature_threshold, float bottom_flow_value_threshold)
static uint32_t compute_diff(uint8_t *image, uint16_t offx, uint16_t offy, uint16_t row_size, uint8_t window_size)
Compute the average pixel gradient of all horizontal and vertical steps.
static uint32_t compute_subpixel(uint8_t *image1, uint8_t *image2, uint16_t off1x, uint16_t off1y, uint16_t off2x, uint16_t off2y, uint32_t *acc, uint16_t row_size, uint16_t window_size)
Compute SAD distances of subpixel shift of two pixel patterns.
static uint32_t compute_sad(uint8_t *image1, uint8_t *image2, uint16_t off1x, uint16_t off1y, uint16_t off2x, uint16_t off2y, uint16_t row_size, uint16_t window_size)
Compute SAD of two pixel windows.
float _bottom_flow_value_threshold
const AP_HAL::HAL & hal
-*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
uint8_t compute_flow(uint8_t *image1, uint8_t *image2, uint32_t delta_time, float *pixel_flow_x, float *pixel_flow_y)