mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-22 04:13:39 +08:00
Opticflow pyramid build FPS improvements (#2825)
* Speeds up convolution and updates airframe settings * Reduces PYRAMID_LEVEL to 0 for both cameras * Updates comments and airframe settings
This commit is contained in:
@@ -24,25 +24,32 @@
|
||||
<configure name="USE_MAGNETOMETER" value="FALSE"/>
|
||||
</module>
|
||||
<module name="ins" type="hff_extended"/>
|
||||
|
||||
<define name="USE_SONAR"/>
|
||||
<module name="pose_history"/>
|
||||
<module name="bebop_cam"/>
|
||||
|
||||
<module name="bebop_cam">
|
||||
<!-- IMPORTANT to limit these or FPS drops significantly -->
|
||||
<define name="MT9F002_TARGET_FPS" value="30"/> <!-- Front cam -->
|
||||
<define name="MT9V117_TARGET_FPS" value="60"/> <!-- Bottom cam -->
|
||||
</module>
|
||||
<module name="cv_opticflow">
|
||||
<define name="OPTICFLOW_CAMERA" value="bottom_camera"/>
|
||||
<define name="OPTICFLOW_DEROTATION_CORRECTION_FACTOR_X" value="0.8"/> <!--Obtained from a linefit-->
|
||||
<define name="OPTICFLOW_DEROTATION_CORRECTION_FACTOR_Y" value="0.85"/> <!--Obtained from a linefit-->
|
||||
<define name="OPTICFLOW_MAX_TRACK_CORNERS" value="10"/>
|
||||
<configure name="OPTICFLOW_MAX_TRACK_CORNERS" value="20"/>
|
||||
<define name="OPTICFLOW_FEATURE_MANAGEMENT" value="0"/>
|
||||
<define name="OPTICFLOW_FPS" value="5"/>
|
||||
<define name="OPTICFLOW_SHOW_FLOW" value="1"/>
|
||||
<define name="OPTICFLOW_FPS" value="60"/>
|
||||
<define name="OPTICFLOW_PYRAMID_LEVEL" value="0"/>
|
||||
<define name="OPTICFLOW_SHOW_FLOW" value="0"/>
|
||||
|
||||
<define name="OPTICFLOW_CAMERA2" value="front_camera"/>
|
||||
<define name="OPTICFLOW_DEROTATION_CORRECTION_FACTOR_X_CAMERA2" value="0.8"/> <!--Obtained from a linefit-->
|
||||
<define name="OPTICFLOW_DEROTATION_CORRECTION_FACTOR_Y_CAMERA2" value="0.85"/> <!--Obtained from a linefit-->
|
||||
<define name="OPTICFLOW_MAX_TRACK_CORNERS_CAMERA2" value="10"/>
|
||||
<configure name="OPTICFLOW_MAX_TRACK_CORNERS_CAMERA2" value="30"/>
|
||||
<define name="OPTICFLOW_FEATURE_MANAGEMENT_CAMERA2" value="0"/>
|
||||
<define name="OPTICFLOW_FPS_CAMERA2" value="5"/>
|
||||
<define name="OPTICFLOW_SHOW_FLOW_CAMERA2" value="1"/>
|
||||
<define name="OPTICFLOW_FPS_CAMERA2" value="20"/>
|
||||
<define name="OPTICFLOW_PYRAMID_LEVEL_CAMERA2" value="0"/>
|
||||
<define name="OPTICFLOW_SHOW_FLOW_CAMERA2" value="0"/>
|
||||
</module>
|
||||
|
||||
<module name="video_capture">
|
||||
@@ -199,9 +206,4 @@
|
||||
<define name="MAX_BAT_LEVEL" value="12.4" unit="V"/>
|
||||
</section>
|
||||
|
||||
<section name="OPTICFLOW" prefix="OPTICFLOW_">
|
||||
<define name="CORNER_METHOD" value="0"/>
|
||||
<define name="MAX_TRACK_CORNERS" value="10"/>
|
||||
</section>
|
||||
|
||||
</airframe>
|
||||
|
||||
@@ -140,13 +140,20 @@ void image_to_grayscale(struct image_t *input, struct image_t *output)
|
||||
output->pprz_ts = input->pprz_ts;
|
||||
|
||||
// Copy the pixels
|
||||
for (int y = 0; y < output->h; y++) {
|
||||
for (int x = 0; x < output->w; x++) {
|
||||
if (output->type == IMAGE_YUV422) {
|
||||
int height = output->h;
|
||||
int width = output->w;
|
||||
if (output->type == IMAGE_YUV422) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
*dest++ = 127; // U / V
|
||||
*dest++ = *source; // Y
|
||||
source += 2;
|
||||
}
|
||||
*dest++ = *source; // Y
|
||||
source += 2;
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height * width; y++) {
|
||||
*dest++ = *source++; // Y
|
||||
source++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,9 +401,10 @@ void image_add_border(struct image_t *input, struct image_t *output, uint8_t bor
|
||||
|
||||
/**
|
||||
* This function takes previous padded pyramid level and outputs next level of pyramid without padding.
|
||||
* For calculating new pixel value 5x5 filter matrix suggested by Bouguet is used:
|
||||
* [1/16 1/8 3/4 1/8 1/16]' x [1/16 1/8 3/4 1/8 1/16]
|
||||
* To avoid decimal numbers, all coefficients are multiplied by 10000.
|
||||
* For calculating new pixel value 3x3 Gaussian filter matrix is used:
|
||||
* [1/4 1/2 1/4]' x [1/4 1/2 1/4]
|
||||
* Blur and downsample is performed with two 1D convolutions (horizontal then vertical)
|
||||
* instead of a single 2D convolution, to increase performance
|
||||
*
|
||||
* @param[in] *input - input image (grayscale only)
|
||||
* @param[out] *output - the output image
|
||||
@@ -415,27 +423,30 @@ void pyramid_next_level(struct image_t *input, struct image_t *output, uint8_t b
|
||||
uint16_t w = input->w;
|
||||
int32_t sum = 0;
|
||||
|
||||
// Horizontal convolution
|
||||
for (uint16_t i = 0; i != output->h; i++) {
|
||||
|
||||
for (uint16_t j = 0; j != output->w; j++) {
|
||||
row = border_size + 2 * i; // First skip border, then every second pixel
|
||||
col = border_size + 2 * j;
|
||||
|
||||
sum = 39 * (input_buf[(row - 2) * w + (col - 2)] + input_buf[(row - 2) * w + (col + 2)] +
|
||||
input_buf[(row + 2) * w + (col - 2)] + input_buf[(row + 2) * w + (col + 2)]);
|
||||
sum += 156 * (input_buf[(row - 2) * w + (col - 1)] + input_buf[(row - 2) * w + (col + 1)] +
|
||||
input_buf[(row - 1) * w + (col + 2)] + input_buf[(row + 1) * w + (col - 2)]
|
||||
+ input_buf[(row + 1) * w + (col + 2)] + input_buf[(row + 2) * w + (col - 1)] + input_buf[(row + 2) * w + (col + 1)] +
|
||||
input_buf[(row - 1) * w + (col - 2)]);
|
||||
sum += 234 * (input_buf[(row - 2) * w + (col)] + input_buf[(row) * w + (col - 2)] +
|
||||
input_buf[(row) * w + (col + 2)] + input_buf[(row + 2) * w + (col)]);
|
||||
sum += 625 * (input_buf[(row - 1) * w + (col - 1)] + input_buf[(row - 1) * w + (col + 1)] +
|
||||
input_buf[(row + 1) * w + (col - 1)] + input_buf[(row + 1) * w + (col + 1)]);
|
||||
sum += 938 * (input_buf[(row - 1) * w + (col)] + input_buf[(row) * w + (col - 1)] +
|
||||
input_buf[(row) * w + (col + 1)] + input_buf[(row + 1) * w + (col)]);
|
||||
sum += 1406 * input_buf[(row) * w + (col)];
|
||||
sum = (input_buf[row * w + col]) >> 1;
|
||||
sum += (input_buf[row * w + col + 1] + input_buf[row * w + col - 1]) >> 2;
|
||||
|
||||
output_buf[i * output->w + j] = sum / 10000;
|
||||
output_buf[i * output->w + j] = sum;
|
||||
}
|
||||
}
|
||||
// Vertical convolution
|
||||
w = output->w;
|
||||
for (uint16_t i = 0; i != output->h - border_size; i++) {
|
||||
for (uint16_t j = 0; j != output->w - border_size; j++) {
|
||||
// Wrong to add border_size again, but offset of a few px acceptable inaccuracy
|
||||
row = border_size + i;
|
||||
col = border_size + j;
|
||||
|
||||
sum = (output_buf[row * w + col]) >> 1;
|
||||
sum += (output_buf[(row + 1) * w + col] + output_buf[(row - 1) * w + col]) >> 2;
|
||||
|
||||
output_buf[i * output->w + j] = sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user