Skip to content

Commit

Permalink
Draw line with color, plus extra functions for drawing crosshairs and…
Browse files Browse the repository at this point in the history
… rectangles (paparazzi#2195)

* Draw line fix so that color actually works, plus extra functions for drawing crosshairs and rectangles.

* Added static and formatted code style
  • Loading branch information
guidoAI authored and kirkscheper committed Dec 1, 2017
1 parent c7da872 commit 237536b
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 20 deletions.
147 changes: 128 additions & 19 deletions sw/airborne/modules/computer_vision/lib/vision/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,19 +552,48 @@ int32_t image_multiply(struct image_t *img_a, struct image_t *img_b, struct imag
* @param[in] *points_cnt The amount of points to show
*/
void image_show_points(struct image_t *img, struct point_t *points, uint16_t points_cnt)
{
uint8_t color[4];
color[0] = 255;
color[1] = 255;
color[2] = 255;
color[3] = 255;

image_show_points_color(img, points, points_cnt, color);

}

/**
* 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 show
* @param[in] *points_cnt The amount of points to show
* @param[in] *color The color of the points as a [U, Y1, V, Y2] uint8_t array, or a uint8_t value pointer for grayscale images.
* Example colors: white = {127, 255, 127, 255}, green = {0, 127, 0, 127};
*/
void image_show_points_color(struct image_t *img, struct point_t *points, uint16_t points_cnt, uint8_t *color)
{
uint8_t *img_buf = (uint8_t *)img->buf;
uint8_t pixel_width = (img->type == IMAGE_YUV422) ? 2 : 1;

int cross_hair = 1;
int size_crosshair = 5;

// Go trough all points and color them
for (int i = 0; i < points_cnt; i++) {
uint32_t idx = pixel_width * points[i].y * img->w + points[i].x * pixel_width;
img_buf[idx] = 255;

// YUV422 consists of 2 pixels
if (img->type == IMAGE_YUV422) {
idx++;
if (!cross_hair) {
uint32_t idx = pixel_width * points[i].y * img->w + points[i].x * pixel_width;
img_buf[idx] = 255;

// YUV422 consists of 2 pixels
if (img->type == IMAGE_YUV422) {
idx++;
img_buf[idx] = 255;
}
} else {
image_draw_crosshair(img, &(points[i]), color, size_crosshair);
}
}
}
Expand All @@ -578,27 +607,24 @@ void image_show_points(struct image_t *img, struct point_t *points, uint16_t poi
*/
void image_show_flow(struct image_t *img, struct flow_t *vectors, uint16_t points_cnt, uint8_t subpixel_factor)
{
static uint8_t color[4] = {255, 255, 255, 255};
static int size_crosshair = 5;

// Go through all the points
for (uint16_t i = 0; i < points_cnt; i++) {
// Draw a line from the original position with the flow vector
struct point_t from = {
vectors[i].pos.x / subpixel_factor,
vectors[i].pos.y / subpixel_factor,
0,
vectors[i].pos.x % subpixel_factor,
vectors[i].pos.y % subpixel_factor
vectors[i].pos.y / subpixel_factor
};
struct point_t to = {
(vectors[i].pos.x + vectors[i].flow_x) / subpixel_factor,
(vectors[i].pos.y + vectors[i].flow_y) / subpixel_factor,
0,
(vectors[i].pos.x + vectors[i].flow_x) % subpixel_factor,
(vectors[i].pos.y + vectors[i].flow_y) % subpixel_factor
(vectors[i].pos.y + vectors[i].flow_y) / subpixel_factor
};
image_draw_line(img, &from, &to);
image_draw_crosshair(img, &to, color, size_crosshair);
}
}

/**
* Get the gradient at a pixel location
* @param[in,out] *img The image
Expand Down Expand Up @@ -670,6 +696,77 @@ void image_gradient_pixel(struct image_t *img, struct point_t *loc, int method,
(*dy) = gradient_y;
}

/**
* Draw a rectangle on the image
* @param[in,out] *img The image to show the line on
* @param[in] x_min start in x
* @param[in] x_max end of x
* @param[in] y_min start in y
* @param[in] y_max end of y
* @param[in] color in [U, Y, V, Y] format
*/
void image_draw_rectangle(struct image_t *img, int x_min, int x_max, int y_min, int y_max, uint8_t *color)
{
struct point_t from, to;

// bottom from left to right:
from.x = x_min;
from.y = y_min;
to.x = x_max;
to.y = y_min;
image_draw_line_color(img, &from, &to, color);

// from bottom right to top right:
from.x = x_max;
from.y = y_min;
to.x = x_max;
to.y = y_max;
image_draw_line_color(img, &from, &to, color);

// from top right to top left:
from.x = x_max;
from.y = y_max;
to.x = x_min;
to.y = y_max;
image_draw_line_color(img, &from, &to, color);

// from top left to bottom left:
from.x = x_min;
from.y = y_max;
to.x = x_min;
to.y = y_min;
image_draw_line_color(img, &from, &to, color);

}

/**
* Draw a cross-hair on the image
* @param[in,out] *img The image to show the line on
* @param[in] loc The location of the cross-hair
* @param[in] color The line color as a [U, Y1, V, Y2] uint8_t array, or a uint8_t value pointer for grayscale images.
* Example colors: white = {127, 255, 127, 255}, green = {0, 127, 0, 127};
* @param[in] size_crosshair Actually the half size of the cross hair
*/
void image_draw_crosshair(struct image_t *img, struct point_t *loc, uint8_t *color, int size_crosshair)
{
struct point_t from, to;

if (loc->x >= size_crosshair && loc->x < img->w - size_crosshair
&& loc->y >= size_crosshair && loc->y < img->h - size_crosshair) {
// draw the lines:
from.x = loc->x - size_crosshair;
from.y = loc->y;
to.x = loc->x + size_crosshair;
to.y = loc->y;
image_draw_line_color(img, &from, &to, color);
from.x = loc->x;
from.y = loc->y - size_crosshair;
to.x = loc->x;
to.y = loc->y + size_crosshair;
image_draw_line_color(img, &from, &to, color);
}
}

/**
* Draw a pink line on the image
* @param[in,out] *img The image to show the line on
Expand All @@ -682,6 +779,7 @@ void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *
image_draw_line_color(img, from, to, color);
}


/**
* Draw a line on the image
* @param[in,out] *img The image to show the line on
Expand All @@ -698,6 +796,8 @@ void image_draw_line_color(struct image_t *img, struct point_t *from, struct poi
uint16_t startx = from->x;
uint16_t starty = from->y;

uint8_t temp_color[4] = {color[0], color[1], color[2], color[3]};

/* compute the distances in both directions */
int32_t delta_x = to->x - from->x;
int32_t delta_y = to->y - from->y;
Expand Down Expand Up @@ -725,15 +825,24 @@ void image_draw_line_color(struct image_t *img, struct point_t *from, struct poi
/* draw the line */
for (uint16_t t = 0; /* starty >= 0 && */ starty < img->h && /* startx >= 0 && */ startx < img->w
&& t <= distance + 1; t++) {

// depending on startx being odd or even, we first have to set U or V
if (startx % 2 == 1) {
temp_color[0] = color[2];
temp_color[2] = color[0];
} else {
temp_color[0] = color[0];
temp_color[2] = color[2];
}
uint32_t buf_loc = img->w * pixel_width * starty + startx * pixel_width;
img_buf[buf_loc] = (t <= 3) ? 0 : color[0]; // u (or grayscale)
img_buf[buf_loc] = temp_color[0]; // u (when startx even)

if (img->type == IMAGE_YUV422) {
img_buf[buf_loc + 1] = color[1]; // y1
img_buf[buf_loc + 1] = temp_color[1]; // y1

if (startx + 1 < img->w) {
img_buf[buf_loc + 2] = (t <= 3) ? 0 : color[2]; // v
img_buf[buf_loc + 3] = color[3]; // y2
img_buf[buf_loc + 2] = temp_color[2]; // v (when startx even)
img_buf[buf_loc + 3] = temp_color[3]; // y2
}
}

Expand Down
5 changes: 4 additions & 1 deletion sw/airborne/modules/computer_vision/lib/vision/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,14 @@ 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_points_color(struct image_t *img, struct point_t *points, uint16_t points_cnt, uint8_t *color);
void image_show_flow(struct image_t *img, struct flow_t *vectors, uint16_t points_cnt, uint8_t subpixel_factor);
void image_draw_crosshair(struct image_t *img, struct point_t *loc, uint8_t *color, int size_crosshair);
void image_draw_rectangle(struct image_t *img, int x_min, int x_max, int y_min, int y_max, uint8_t *color);
void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *to);
void image_draw_line_color(struct image_t *img, struct point_t *from, struct point_t *to, uint8_t *color);
void pyramid_next_level(struct image_t *input, struct image_t *output, uint8_t border_size);
void pyramid_build(struct image_t *input, struct image_t *output_array, uint8_t pyr_level, uint16_t border_size);
void image_gradient_pixel(struct image_t *img, struct point_t *loc, int method, int *dx, int* dy);
void image_gradient_pixel(struct image_t *img, struct point_t *loc, int method, int *dx, int *dy);

#endif

0 comments on commit 237536b

Please sign in to comment.