mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-10 06:59:54 +08:00
[vision] Update some stuff
This commit is contained in:
@@ -427,12 +427,16 @@ void jpeg_encode_image(struct image_t *in, struct image_t *out, uint32_t quality
|
||||
uint16_t i, j;
|
||||
uint8_t *output_ptr = out->buf;
|
||||
uint8_t *input_ptr = in->buf;
|
||||
uint32_t image_format = FOUR_ZERO_ZERO;
|
||||
|
||||
if(in->type == IMAGE_YUV422)
|
||||
image_format = FOUR_TWO_TWO;
|
||||
|
||||
JPEG_ENCODER_STRUCTURE JpegStruct;
|
||||
JPEG_ENCODER_STRUCTURE *jpeg_encoder_structure = &JpegStruct;
|
||||
|
||||
/* Initialization of JPEG control structure */
|
||||
jpeg_initialization(jpeg_encoder_structure, FOUR_TWO_TWO, in->w, in->h);
|
||||
jpeg_initialization(jpeg_encoder_structure, image_format, in->w, in->h);
|
||||
|
||||
/* Quantization Table Initialization */
|
||||
//jpeg_initialize_quantization_tables (quality_factor);
|
||||
@@ -441,7 +445,7 @@ void jpeg_encode_image(struct image_t *in, struct image_t *out, uint32_t quality
|
||||
|
||||
/* Writing Marker Data */
|
||||
if (add_dri_header) {
|
||||
output_ptr = jpeg_write_markers(output_ptr, FOUR_TWO_TWO, in->w, in->h);
|
||||
output_ptr = jpeg_write_markers(output_ptr, image_format, in->w, in->h);
|
||||
}
|
||||
|
||||
for (i = 1; i <= jpeg_encoder_structure->vertical_mcus; i++) {
|
||||
@@ -463,7 +467,7 @@ void jpeg_encode_image(struct image_t *in, struct image_t *out, uint32_t quality
|
||||
read_format(jpeg_encoder_structure, input_ptr);
|
||||
|
||||
/* Encode the data in MCU */
|
||||
output_ptr = jpeg_encodeMCU(jpeg_encoder_structure, FOUR_TWO_TWO, output_ptr);
|
||||
output_ptr = jpeg_encodeMCU(jpeg_encoder_structure, image_format, output_ptr);
|
||||
|
||||
input_ptr += jpeg_encoder_structure->mcu_width_size;
|
||||
}
|
||||
|
||||
@@ -225,12 +225,12 @@ void image_subpixel_window(struct image_t *input, struct image_t *output, struct
|
||||
|
||||
// Calculate the window size
|
||||
uint16_t half_window = output->w / 2;
|
||||
uint16_t subpixel_w = output->w * subpixel_factor;
|
||||
uint16_t subpixel_h = output->h * subpixel_factor;
|
||||
uint16_t subpixel_w = input->w * subpixel_factor;
|
||||
uint16_t subpixel_h = input->h * subpixel_factor;
|
||||
|
||||
// Go through the whole window size in normal coordinates
|
||||
for(uint16_t i = 0; i < output->w; i++) {
|
||||
for(uint16_t j = 0; j < output->w; j++) {
|
||||
for(uint16_t j = 0; j < output->h; j++) {
|
||||
// Calculate the subpixel coordinate
|
||||
uint16_t x = center->x + (i - half_window) * subpixel_factor;
|
||||
uint16_t y = center->y + (j - half_window) * subpixel_factor;
|
||||
@@ -246,9 +246,8 @@ void image_subpixel_window(struct image_t *input, struct image_t *output, struct
|
||||
uint16_t tl_y = orig_y * subpixel_factor;
|
||||
|
||||
// Check if it is the top left pixel
|
||||
uint32_t output_idx = output->w*y + x;
|
||||
if(tl_x == x && tl_y == y) {
|
||||
output_buf[output_idx] = input_buf[input->w*orig_y + orig_x];
|
||||
output_buf[output->w*j + i] = input_buf[input->w*orig_y + orig_x];
|
||||
}
|
||||
else {
|
||||
// Calculate the difference from the top left
|
||||
@@ -262,7 +261,7 @@ void image_subpixel_window(struct image_t *input, struct image_t *output, struct
|
||||
blend += alpha_x * alpha_y * input_buf[input->w*(orig_y+1) + (orig_x+1)];
|
||||
|
||||
// Set the normalized pixel blend
|
||||
output_buf[output_idx] = blend / (subpixel_factor * subpixel_factor);
|
||||
output_buf[output->w*j + i] = blend / (subpixel_factor * subpixel_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,7 +269,7 @@ void image_subpixel_window(struct image_t *input, struct image_t *output, struct
|
||||
|
||||
/**
|
||||
* Calculate the gradients using the following matrix:
|
||||
* [0 0 0; -1 0 1; 0 0 0]
|
||||
* [0 -1 0; -1 0 1; 0 1 0]
|
||||
* @param[in] *input Input grayscale image
|
||||
* @param[out] *dx Output gradient in the X direction (dx->w = input->w-2, dx->h = input->h-2)
|
||||
* @param[out] *dy Output gradient in the Y direction (dx->w = input->w-2, dx->h = input->h-2)
|
||||
@@ -280,13 +279,13 @@ void image_gradients(struct image_t *input, struct image_t *dx, struct image_t *
|
||||
// Fetch the buffers in the correct format
|
||||
uint8_t *input_buf = (uint8_t *)input->buf;
|
||||
int16_t *dx_buf = (int16_t *)dx->buf;
|
||||
int16_t *dy_buf = (int16_t *)dx->buf;
|
||||
int16_t *dy_buf = (int16_t *)dy->buf;
|
||||
|
||||
// Go trough all pixels except the borders
|
||||
for(uint16_t x = 1; x < input->w-1; x++) {
|
||||
for(uint16_t y = 1; y < input->h-1; x++) {
|
||||
dx_buf[(y-1)*dx->w + (x-1)] = -input_buf[y*input->w + x-1] + input_buf[y*input->w + x+1];
|
||||
dy_buf[(y-1)*dx->w + (x-1)] = -input_buf[(y-1)*input->w + x] + input_buf[(y+1)*input->w + x];
|
||||
for(uint16_t y = 1; y < input->h-1; y++) {
|
||||
dx_buf[(y-1)*dx->w + (x-1)] = (int16_t)input_buf[y*input->w + x+1] - (int16_t)input_buf[y*input->w + x-1];
|
||||
dy_buf[(y-1)*dy->w + (x-1)] = (int16_t)input_buf[(y+1)*input->w + x] - (int16_t)input_buf[(y-1)*input->w + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,22 +303,22 @@ void image_calculate_g(struct image_t *dx, struct image_t *dy, int32_t *g)
|
||||
|
||||
// Fetch the buffers in the correct format
|
||||
int16_t *dx_buf = (int16_t *)dx->buf;
|
||||
int16_t *dy_buf = (int16_t *)dx->buf;
|
||||
int16_t *dy_buf = (int16_t *)dy->buf;
|
||||
|
||||
// Calculate the different sums
|
||||
for(uint16_t x = 0; x < dx->w; x++) {
|
||||
for(uint16_t y = 0; y < dy->h; y++) {
|
||||
sum_dxx += (dx_buf[y*dx->w + x] * dx_buf[y*dx->w + x]);
|
||||
sum_dxy += (dx_buf[y*dx->w + x] * dy_buf[y*dy->w + x]);
|
||||
sum_dyy += (dy_buf[y*dy->w + x] * dy_buf[y*dy->w + x]);
|
||||
sum_dxx += ((int32_t)dx_buf[y*dx->w + x] * dx_buf[y*dx->w + x]);
|
||||
sum_dxy += ((int32_t)dx_buf[y*dx->w + x] * dy_buf[y*dy->w + x]);
|
||||
sum_dyy += ((int32_t)dy_buf[y*dy->w + x] * dy_buf[y*dy->w + x]);
|
||||
}
|
||||
}
|
||||
|
||||
// ouput the G vector
|
||||
g[0] = sum_dxx / 255;
|
||||
g[1] = sum_dxy / 255;
|
||||
g[2] = sum_dxy / 255;
|
||||
g[3] = sum_dyy / 255;
|
||||
g[0] = sum_dxx;
|
||||
g[1] = sum_dxy;
|
||||
g[2] = g[1];
|
||||
g[3] = sum_dyy;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,16 +336,16 @@ uint32_t image_difference(struct image_t *img_a, struct image_t *img_b, struct i
|
||||
|
||||
// Fetch the buffers in the correct format
|
||||
uint8_t *img_a_buf = (uint8_t *)img_a->buf;
|
||||
int16_t *img_b_buf = (int16_t *)img_b->buf;
|
||||
uint8_t *img_b_buf = (uint8_t *)img_b->buf;
|
||||
|
||||
// If we want the difference image back
|
||||
if(diff != NULL)
|
||||
diff_buf = (int16_t *)diff->buf;
|
||||
|
||||
// Go trough the imagge pixels and calculate the difference
|
||||
for(uint16_t x = 0; x < img_a->w; x++) {
|
||||
for(uint16_t y = 0; y < img_a->h; y++) {
|
||||
int16_t diff_c = img_a_buf[y*img_a->w +x] - img_b_buf[y*img_b->w +x];
|
||||
for(uint16_t x = 0; x < img_b->w; x++) {
|
||||
for(uint16_t y = 0; y < img_b->h; y++) {
|
||||
int16_t diff_c = img_a_buf[(y+1)*img_a->w +(x+1)] - img_b_buf[y*img_b->w +x];
|
||||
sum_diff2 += diff_c*diff_c;
|
||||
|
||||
// Set the difference image
|
||||
@@ -395,6 +394,7 @@ int32_t image_multiply(struct image_t *img_a, struct image_t *img_b, struct imag
|
||||
/**
|
||||
* Show points in an image by coloring them through giving
|
||||
* the pixels the maximum value.
|
||||
* This works with YUV422 and grayscale images
|
||||
* @param[in,out] *img The image to place the points on
|
||||
* @param[in] *points The points to sohw
|
||||
* @param[in] *points_cnt The amount of points to show
|
||||
@@ -416,3 +416,87 @@ void image_show_points(struct image_t *img, struct point_t *points, uint16_t poi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the flow from a specific point to a new point
|
||||
* This works on YUV422 and Grayscale images
|
||||
* @param[in,out] *img The image to show the flow on
|
||||
* @param[in] *points The initial point location
|
||||
* @param[in] *new_points The new point locations
|
||||
* @param[in] *points_cnt The amount of points to show
|
||||
* @param[in] *status_points The status of the specific point (TRUE is tracked, FALSE is untracked)
|
||||
*/
|
||||
void image_show_flow(struct image_t *img, struct point_t *points, struct point_t *new_points, uint16_t points_cnt, bool_t *status_points)
|
||||
{
|
||||
// Go through all the points
|
||||
for(uint16_t i = 0; i < points_cnt; i++) {
|
||||
// Check if we are still tracking
|
||||
if(!status_points[i])
|
||||
continue;
|
||||
|
||||
//printf("Drawing line\n");
|
||||
|
||||
// Draw a line from points[i] to new_points[i]
|
||||
image_draw_line(img, &points[i], &new_points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a line on the image
|
||||
* @param[in,out] *img The image to show the line on
|
||||
* @param[in] *from The point to draw from
|
||||
* @param[in] *to The point to draw to
|
||||
*/
|
||||
void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *to)
|
||||
{
|
||||
int xerr=0, yerr=0;
|
||||
uint8_t *img_buf = (uint8_t *)img->buf;
|
||||
uint8_t pixel_width = (img->type == IMAGE_YUV422)? 2 : 1;
|
||||
uint16_t startx = from->x;
|
||||
uint16_t starty = from->y;
|
||||
|
||||
/* compute the distances in both directions */
|
||||
int32_t delta_x = from->x - to->x;
|
||||
int32_t delta_y = from->y - to->y;
|
||||
|
||||
/* Compute the direction of the increment,
|
||||
an increment of 0 means either a horizontal or vertical
|
||||
line.
|
||||
*/
|
||||
int8_t incx, incy;
|
||||
if(delta_x>0) incx=1;
|
||||
else if(delta_x==0) incx=0;
|
||||
else incx=-1;
|
||||
|
||||
if(delta_y>0) incy=1;
|
||||
else if(delta_y==0) incy=0;
|
||||
else incy=-1;
|
||||
|
||||
/* determine which distance is greater */
|
||||
uint16_t distance = 0;
|
||||
delta_x = abs(delta_x);
|
||||
delta_y = abs(delta_y);
|
||||
if(delta_x > delta_y) distance = delta_x*20;
|
||||
else distance = delta_y*20;
|
||||
|
||||
/* draw the line */
|
||||
for(uint16_t t = 0; t <= distance+1; t++) {
|
||||
img_buf[img->w*pixel_width*starty + startx*pixel_width] = 255;
|
||||
|
||||
if(img->type == IMAGE_YUV422) {
|
||||
img_buf[img->w*pixel_width*starty + startx*pixel_width] = 255;
|
||||
img_buf[img->w*pixel_width*starty + startx*pixel_width +1] = 255;
|
||||
}
|
||||
|
||||
xerr += delta_x;
|
||||
yerr += delta_y;
|
||||
if(xerr > distance) {
|
||||
xerr -= distance;
|
||||
startx += incx;
|
||||
}
|
||||
if(yerr > distance) {
|
||||
yerr -= distance;
|
||||
starty += incy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,5 +69,7 @@ void image_calculate_g(struct image_t *dx, struct image_t *dy, int32_t *g);
|
||||
uint32_t image_difference(struct image_t *img_a, struct image_t *img_b, struct image_t *diff);
|
||||
int32_t image_multiply(struct image_t *img_a, struct image_t *img_b, struct image_t *mult);
|
||||
void image_show_points(struct image_t *img, struct point_t *points, uint16_t points_cnt);
|
||||
void image_show_flow(struct image_t *img, struct point_t *points, struct point_t *new_points, uint16_t points_cnt, bool_t *status_points);
|
||||
void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *to);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -114,6 +114,7 @@ void opticFlowLK(struct image_t *new_img, struct image_t *old_img, struct point_
|
||||
status[p] = FALSE;
|
||||
continue;
|
||||
}
|
||||
//printf("G[0]: %d, G[1]: %d, G[2]: %d, G[3]: %d, Det: %d\n", G[0], G[1], G[2], G[3], Det);
|
||||
|
||||
// (4) iterate over taking steps in the image to minimize the error:
|
||||
memcpy(&new_points[p], &points[p], sizeof(struct point_t));
|
||||
@@ -151,6 +152,9 @@ void opticFlowLK(struct image_t *new_img, struct image_t *old_img, struct point_
|
||||
break;
|
||||
}
|
||||
|
||||
//if(status[p])
|
||||
// printf("Got flow...\n");
|
||||
|
||||
// Convert the point back to the original coordinate (TODO: maybe round it as it is closer to the original)
|
||||
new_points[p].x /= subpixel_factor;
|
||||
new_points[p].y /= subpixel_factor;
|
||||
|
||||
@@ -106,9 +106,15 @@ void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_
|
||||
// FAST corner detection (TODO: non fixed threashold)
|
||||
struct point_t *fast9_points = fast9_detect(img, 20, 5, &result->corner_cnt);
|
||||
|
||||
#if OPTICFLOW_SHOW_CORNERS
|
||||
//#if OPTICFLOW_SHOW_CORNERS
|
||||
image_show_points(img, fast9_points, result->corner_cnt);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
if(result->corner_cnt < 1) {
|
||||
free(fast9_points);
|
||||
image_copy(&opticflow->img_gray, &opticflow->prev_img_gray);
|
||||
return;
|
||||
}
|
||||
|
||||
// *************************************************************************************
|
||||
// Corner Tracking
|
||||
@@ -118,6 +124,7 @@ void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_
|
||||
bool_t *tracked_points = malloc(sizeof(bool_t) * result->corner_cnt);
|
||||
opticFlowLK(&opticflow->img_gray, &opticflow->prev_img_gray, fast9_points, result->corner_cnt,
|
||||
new_points, tracked_points, 5, 100, 2);
|
||||
image_show_flow(img, fast9_points, new_points, result->corner_cnt, tracked_points);
|
||||
|
||||
// Remove points if we lost tracking
|
||||
/* for (int i = count_fil - 1; i >= 0; i--) {
|
||||
|
||||
@@ -171,15 +171,41 @@ static void *opticflow_module_calc(void *data __attribute__((unused))) {
|
||||
pthread_mutex_unlock(&opticflow_mutex);
|
||||
|
||||
#ifdef OPTICFLOW_DEBUG
|
||||
jpeg_encode_image(&img, &img_jpeg, 50, FALSE);
|
||||
jpeg_encode_image(&img, &img_jpeg, 80, FALSE);
|
||||
rtp_frame_send(
|
||||
&VIEWVIDEO_DEV, // UDP device
|
||||
&img_jpeg,
|
||||
0, // Format 422
|
||||
50, // Jpeg-Quality
|
||||
80, // Jpeg-Quality
|
||||
0, // DRI Header
|
||||
0 // 90kHz time increment
|
||||
);
|
||||
|
||||
// Open process to send using netcat (in a fork because sometimes kills itself???)
|
||||
/*pid_t pid = fork();
|
||||
|
||||
if(pid < 0) {
|
||||
printf("[viewvideo] Could not create netcat fork.\n");
|
||||
}
|
||||
else if(pid ==0) {
|
||||
// We are the child and want to send the image
|
||||
FILE *netcat = popen("nc 192.168.1.2 5000 2>/dev/null", "w");
|
||||
if (netcat != NULL) {
|
||||
fwrite(img_jpeg.buf, sizeof(uint8_t), img_jpeg.buf_size, netcat);
|
||||
pclose(netcat); // Ignore output, because it is too much when not connected
|
||||
} else {
|
||||
printf("[viewvideo] Failed to open netcat process.\n");
|
||||
}
|
||||
|
||||
// Exit the program since we don't want to continue after transmitting
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
// We want to wait until the child is finished
|
||||
wait(NULL);
|
||||
}*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Free the image
|
||||
|
||||
Reference in New Issue
Block a user