mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-28 18:07:25 +08:00
Draw line with color, plus extra functions for drawing crosshairs and rectangles (#2195)
* Draw line fix so that color actually works, plus extra functions for drawing crosshairs and rectangles. * Added static and formatted code style
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user