Paparazzi UAS  v5.12_stable-4-g9b43e9b
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
image.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Freek van Tienen <freek.v.tienen@gmail.com>
3  *
4  * This file is part of Paparazzi.
5  *
6  * Paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
27 #include "image.h"
28 #include <stdlib.h>
29 #include <string.h>
30 
38 void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
39 {
40  // Set the variables
41  img->type = type;
42  img->w = width;
43  img->h = height;
44 
45  // Depending on the type the size differs
46  if (type == IMAGE_YUV422) {
47  img->buf_size = sizeof(uint8_t) * 2 * width * height;
48  } else if (type == IMAGE_JPEG) {
49  img->buf_size = sizeof(uint8_t) * 2 * width * height; // At maximum quality this is enough
50  } else if (type == IMAGE_GRADIENT) {
51  img->buf_size = sizeof(int16_t) * width * height;
52  } else {
53  img->buf_size = sizeof(uint8_t) * width * height;
54  }
55 
56  img->buf = malloc(img->buf_size);
57 }
58 
63 void image_free(struct image_t *img)
64 {
65  if (img->buf != NULL) {
66  free(img->buf);
67  img->buf = NULL;
68  }
69 }
70 
77 void image_copy(struct image_t *input, struct image_t *output)
78 {
79  if (input->type != output->type) {
80  return;
81  }
82 
83  output->w = input->w;
84  output->h = input->h;
85  output->buf_size = input->buf_size;
86  output->ts = input->ts;
87  memcpy(output->buf, input->buf, input->buf_size);
88 }
89 
97 void image_switch(struct image_t *a, struct image_t *b)
98 {
99  /* Remember everything from image a */
100  struct image_t old_a;
101  memcpy(&old_a, a, sizeof(struct image_t));
102 
103  /* Copy everything from b to a */
104  memcpy(a, b, sizeof(struct image_t));
105 
106  /* Copy everything from the remembered a to b */
107  memcpy(b, &old_a, sizeof(struct image_t));
108 }
109 
116 void image_to_grayscale(struct image_t *input, struct image_t *output)
117 {
118  uint8_t *source = input->buf;
119  uint8_t *dest = output->buf;
120  source++;
121 
122  // Copy the creation timestamp (stays the same)
123  output->ts = input->ts;
124 
125  // Copy the pixels
126  for (int y = 0; y < output->h; y++) {
127  for (int x = 0; x < output->w; x++) {
128  if (output->type == IMAGE_YUV422) {
129  *dest++ = 127; // U / V
130  }
131  *dest++ = *source; // Y
132  source += 2;
133  }
134  }
135 }
136 
149 uint16_t image_yuv422_colorfilt(struct image_t *input, struct image_t *output, uint8_t y_m, uint8_t y_M, uint8_t u_m,
150  uint8_t u_M, uint8_t v_m, uint8_t v_M)
151 {
152  uint16_t cnt = 0;
153  uint8_t *source = input->buf;
154  uint8_t *dest = output->buf;
155 
156  // Copy the creation timestamp (stays the same)
157  output->ts = input->ts;
158 
159  // Go trough all the pixels
160  for (uint16_t y = 0; y < output->h; y++) {
161  for (uint16_t x = 0; x < output->w; x += 2) {
162  // Check if the color is inside the specified values
163  if (
164  (dest[1] >= y_m)
165  && (dest[1] <= y_M)
166  && (dest[0] >= u_m)
167  && (dest[0] <= u_M)
168  && (dest[2] >= v_m)
169  && (dest[2] <= v_M)
170  ) {
171  cnt ++;
172  // UYVY
173  dest[0] = 64; // U
174  dest[1] = source[1]; // Y
175  dest[2] = 255; // V
176  dest[3] = source[3]; // Y
177  } else {
178  // UYVY
179  char u = source[0] - 127;
180  u /= 4;
181  dest[0] = 127; // U
182  dest[1] = source[1]; // Y
183  u = source[2] - 127;
184  u /= 4;
185  dest[2] = 127; // V
186  dest[3] = source[3]; // Y
187  }
188 
189  // Go to the next 2 pixels
190  dest += 4;
191  source += 4;
192  }
193  }
194  return cnt;
195 }
196 
213 void image_yuv422_downsample(struct image_t *input, struct image_t *output, uint16_t downsample)
214 {
215  uint8_t *source = input->buf;
216  uint8_t *dest = output->buf;
217  uint16_t pixelskip = (downsample - 1) * 2;
218 
219  // Copy the creation timestamp (stays the same)
220  output->ts = input->ts;
221 
222  // Go trough all the pixels
223  for (uint16_t y = 0; y < output->h; y++) {
224  for (uint16_t x = 0; x < output->w; x += 2) {
225  // YUYV
226  *dest++ = *source++; // U
227  *dest++ = *source++; // Y
228  *dest++ = *source++; // V
229  source += pixelskip;
230  *dest++ = *source++; // Y
231  source += pixelskip;
232  }
233  // read 1 in every 'downsample' rows, so skip (downsample-1) rows after reading the first
234  source += (downsample - 1) * input->w * 2;
235  }
236 }
237 
245 void image_add_border(struct image_t *input, struct image_t *output, uint8_t border_size)
246 {
247  // Create padded image based on input
248  image_create(output, input->w + 2 * border_size, input->h + 2 * border_size, input->type);
249 
250  uint8_t *input_buf = (uint8_t *)input->buf;
251  uint8_t *output_buf = (uint8_t *)output->buf;
252 
253  // Skip first `border_size` rows, iterate through next input->h rows
254  for (uint16_t i = border_size; i != (output->h - border_size); i++) {
255 
256  // Mirror first `border_size` columns
257  for (uint8_t j = 0; j != border_size; j++) {
258  output_buf[i * output->w + (border_size - 1 - j)] = input_buf[(i - border_size) * input->w + j];
259  }
260 
261  // Copy corresponding row values from input image
262  memcpy(&output_buf[i * output->w + border_size], &input_buf[(i - border_size) * input->w], sizeof(uint8_t) * input->w);
263 
264  // Mirror last `border_size` columns
265  for (uint8_t j = 0; j != border_size; j++) {
266  output_buf[i * output->w + output->w - border_size + j] = output_buf[i * output->w + output->w - border_size - 1 - j];
267  }
268  }
269 
270  // Mirror first `border_size` and last `border_size` rows
271  for (uint8_t i = 0; i != border_size; i++) {
272  memcpy(&output_buf[(border_size - 1) * output->w - i * output->w], &output_buf[border_size * output->w + i * output->w],
273  sizeof(uint8_t) * output->w);
274  memcpy(&output_buf[(output->h - border_size) * output->w + i * output->w],
275  &output_buf[(output->h - border_size - 1) * output->w - i * output->w], sizeof(uint8_t) * output->w);
276  }
277 }
278 
290 void pyramid_next_level(struct image_t *input, struct image_t *output, uint8_t border_size)
291 {
292  // Create output image, new image size is half the size of input image without padding (border)
293  image_create(output, (input->w + 1 - 2 * border_size) / 2, (input->h + 1 - 2 * border_size) / 2, input->type);
294 
295  uint8_t *input_buf = (uint8_t *)input->buf;
296  uint8_t *output_buf = (uint8_t *)output->buf;
297 
298  uint16_t row, col; // coordinates of the central pixel; pixel being calculated in input matrix; center of filer matrix
299  uint16_t w = input->w;
300  int32_t sum = 0;
301 
302  for (uint16_t i = 0; i != output->h; i++) {
303 
304  for (uint16_t j = 0; j != output->w; j++) {
305  row = border_size + 2 * i; // First skip border, then every second pixel
306  col = border_size + 2 * j;
307 
308  sum = 39 * (input_buf[(row - 2) * w + (col - 2)] + input_buf[(row - 2) * w + (col + 2)] +
309  input_buf[(row + 2) * w + (col - 2)] + input_buf[(row + 2) * w + (col + 2)]);
310  sum += 156 * (input_buf[(row - 2) * w + (col - 1)] + input_buf[(row - 2) * w + (col + 1)] +
311  input_buf[(row - 1) * w + (col + 2)] + input_buf[(row + 1) * w + (col - 2)]
312  + input_buf[(row + 1) * w + (col + 2)] + input_buf[(row + 2) * w + (col - 1)] + input_buf[(row + 2) * w + (col + 1)] +
313  input_buf[(row - 1) * w + (col - 2)]);
314  sum += 234 * (input_buf[(row - 2) * w + (col)] + input_buf[(row) * w + (col - 2)] +
315  input_buf[(row) * w + (col + 2)] + input_buf[(row + 2) * w + (col)]);
316  sum += 625 * (input_buf[(row - 1) * w + (col - 1)] + input_buf[(row - 1) * w + (col + 1)] +
317  input_buf[(row + 1) * w + (col - 1)] + input_buf[(row + 1) * w + (col + 1)]);
318  sum += 938 * (input_buf[(row - 1) * w + (col)] + input_buf[(row) * w + (col - 1)] +
319  input_buf[(row) * w + (col + 1)] + input_buf[(row + 1) * w + (col)]);
320  sum += 1406 * input_buf[(row) * w + (col)];
321 
322  output_buf[i * output->w + j] = sum / 10000;
323  }
324  }
325 }
326 
327 
337 void pyramid_build(struct image_t *input, struct image_t *output_array, uint8_t pyr_level, uint8_t border_size)
338 {
339  // Pad input image and save it as '0' pyramid level
340  image_add_border(input, &output_array[0], border_size);
341 
342  // Temporary holds 'i' level version of original image to be padded and saved as 'i' pyramid level
343  struct image_t temp;
344 
345  for (uint8_t i = 1; i != pyr_level + 1; i++) {
346  pyramid_next_level(&output_array[i - 1], &temp, border_size);
347  image_add_border(&temp, &output_array[i], border_size);
348  image_free(&temp);
349  }
350 }
351 
364 void image_subpixel_window(struct image_t *input, struct image_t *output, struct point_t *center,
365  uint32_t subpixel_factor, uint8_t border_size)
366 {
367  uint8_t *input_buf = (uint8_t *)input->buf;
368  uint8_t *output_buf = (uint8_t *)output->buf;
369 
370  // Calculate the window size
371  uint16_t half_window = output->w / 2;
372 
373  uint32_t subpixel_w = (input->w -2) * subpixel_factor;
374  uint32_t subpixel_h = (input->h -2) * subpixel_factor;
375 
376  // Go through the whole window size in normal coordinates
377  for (uint16_t i = 0; i < output->w; i++) {
378  for (uint16_t j = 0; j < output->h; j++) {
379  // Calculate the subpixel coordinate
380  uint32_t x = center->x + border_size * subpixel_factor + (i - half_window) * subpixel_factor;
381  uint32_t y = center->y + border_size * subpixel_factor + (j - half_window) * subpixel_factor;
382 
383  BoundUpper(x, subpixel_w);
384  BoundUpper(y, subpixel_h);
385 
386  // Calculate the original pixel coordinate
387  uint16_t orig_x = x / subpixel_factor;
388  uint16_t orig_y = y / subpixel_factor;
389 
390  // Calculate top left (in subpixel coordinates)
391  uint32_t tl_x = orig_x * subpixel_factor;
392  uint32_t tl_y = orig_y * subpixel_factor;
393 
394  // Check if it is the top left pixel
395  if (tl_x == x && tl_y == y) {
396  output_buf[output->w * j + i] = input_buf[input->w * orig_y + orig_x];
397  } else {
398  // Calculate the difference from the top left
399  uint32_t alpha_x = (x - tl_x);
400  uint32_t alpha_y = (y - tl_y);
401 
402  // Blend from the 4 surrounding pixels
403  uint32_t blend = (subpixel_factor - alpha_x) * (subpixel_factor - alpha_y) * input_buf[input->w * orig_y + orig_x];
404  blend += alpha_x * (subpixel_factor - alpha_y) * input_buf[input->w * orig_y + (orig_x + 1)];
405  blend += (subpixel_factor - alpha_x) * alpha_y * input_buf[input->w * (orig_y + 1) + orig_x];
406  blend += alpha_x * alpha_y * input_buf[input->w * (orig_y + 1) + (orig_x + 1)];
407 
408  // Set the normalized pixel blend
409  output_buf[output->w * j + i] = blend / (subpixel_factor * subpixel_factor);
410  }
411  }
412  }
413 }
414 
422 void image_gradients(struct image_t *input, struct image_t *dx, struct image_t *dy)
423 {
424  // Fetch the buffers in the correct format
425  uint8_t *input_buf = (uint8_t *)input->buf;
426  int16_t *dx_buf = (int16_t *)dx->buf;
427  int16_t *dy_buf = (int16_t *)dy->buf;
428 
429  // Go trough all pixels except the borders
430  for (uint16_t x = 1; x < input->w - 1; x++) {
431  for (uint16_t y = 1; y < input->h - 1; y++) {
432  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];
433  dy_buf[(y - 1)*dy->w + (x - 1)] = (int16_t)input_buf[(y + 1) * input->w + x] - (int16_t)
434  input_buf[(y - 1) * input->w + x];
435  }
436  }
437 }
438 
446 void image_calculate_g(struct image_t *dx, struct image_t *dy, int32_t *g)
447 {
448  int32_t sum_dxx = 0, sum_dxy = 0, sum_dyy = 0;
449 
450  // Fetch the buffers in the correct format
451  int16_t *dx_buf = (int16_t *)dx->buf;
452  int16_t *dy_buf = (int16_t *)dy->buf;
453 
454  // Calculate the different sums
455  for (uint16_t x = 0; x < dx->w; x++) {
456  for (uint16_t y = 0; y < dy->h; y++) {
457  sum_dxx += ((int32_t)dx_buf[y * dx->w + x] * dx_buf[y * dx->w + x]);
458  sum_dxy += ((int32_t)dx_buf[y * dx->w + x] * dy_buf[y * dy->w + x]);
459  sum_dyy += ((int32_t)dy_buf[y * dy->w + x] * dy_buf[y * dy->w + x]);
460  }
461  }
462 
463  // output the G vector
464  g[0] = sum_dxx / 255;
465  g[1] = sum_dxy / 255;
466  g[2] = g[1];
467  g[3] = sum_dyy / 255;
468 }
469 
478 uint32_t image_difference(struct image_t *img_a, struct image_t *img_b, struct image_t *diff)
479 {
480  uint32_t sum_diff2 = 0;
481  int16_t *diff_buf = NULL;
482 
483  // Fetch the buffers in the correct format
484  uint8_t *img_a_buf = (uint8_t *)img_a->buf;
485  uint8_t *img_b_buf = (uint8_t *)img_b->buf;
486 
487  // If we want the difference image back
488  if (diff != NULL) {
489  diff_buf = (int16_t *)diff->buf;
490  }
491 
492  // Go trough the imagge pixels and calculate the difference
493  for (uint16_t x = 0; x < img_b->w; x++) {
494  for (uint16_t y = 0; y < img_b->h; y++) {
495  int16_t diff_c = img_a_buf[(y + 1) * img_a->w + (x + 1)] - img_b_buf[y * img_b->w + x];
496  sum_diff2 += diff_c * diff_c;
497 
498  // Set the difference image
499  if (diff_buf != NULL) {
500  diff_buf[y * diff->w + x] = diff_c;
501  }
502  }
503  }
504 
505  return sum_diff2;
506 }
507 
516 int32_t image_multiply(struct image_t *img_a, struct image_t *img_b, struct image_t *mult)
517 {
518  int32_t sum = 0;
519  int16_t *img_a_buf = (int16_t *)img_a->buf;
520  int16_t *img_b_buf = (int16_t *)img_b->buf;
521  int16_t *mult_buf = NULL;
522 
523  // When we want an output
524  if (mult != NULL) {
525  mult_buf = (int16_t *)mult->buf;
526  }
527 
528  // Calculate the multiplication
529  for (uint16_t x = 0; x < img_a->w; x++) {
530  for (uint16_t y = 0; y < img_a->h; y++) {
531  int32_t mult_c = img_a_buf[y * img_a->w + x] * img_b_buf[y * img_b->w + x];
532  sum += mult_c;
533 
534  // Set the difference image
535  if (mult_buf != NULL) {
536  mult_buf[y * mult->w + x] = mult_c;
537  }
538  }
539  }
540 
541  return sum;
542 }
543 
552 void image_show_points(struct image_t *img, struct point_t *points, uint16_t points_cnt)
553 {
554  uint8_t *img_buf = (uint8_t *)img->buf;
555  uint8_t pixel_width = (img->type == IMAGE_YUV422) ? 2 : 1;
556 
557  // Go trough all points and color them
558  for (int i = 0; i < points_cnt; i++) {
559  uint32_t idx = pixel_width * points[i].y * img->w + points[i].x * pixel_width;
560  img_buf[idx] = 255;
561 
562  // YUV422 consists of 2 pixels
563  if (img->type == IMAGE_YUV422) {
564  idx++;
565  img_buf[idx] = 255;
566  }
567  }
568 }
569 
577 void image_show_flow(struct image_t *img, struct flow_t *vectors, uint16_t points_cnt, uint8_t subpixel_factor)
578 {
579  // Go through all the points
580  for (uint16_t i = 0; i < points_cnt; i++) {
581  // Draw a line from the original position with the flow vector
582  struct point_t from = {
583  vectors[i].pos.x / subpixel_factor,
584  vectors[i].pos.y / subpixel_factor
585  };
586  struct point_t to = {
587  (vectors[i].pos.x + vectors[i].flow_x) / subpixel_factor,
588  (vectors[i].pos.y + vectors[i].flow_y) / subpixel_factor
589  };
590  image_draw_line(img, &from, &to);
591  }
592 }
593 
600 void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *to) {
601  static uint8_t color[4] = {255, 255, 255, 255};
602  image_draw_line_color(img, from, to, color);
603 }
604 
613 void image_draw_line_color(struct image_t *img, struct point_t *from, struct point_t *to, uint8_t *color)
614 {
615  int xerr = 0, yerr = 0;
616  uint8_t *img_buf = (uint8_t *)img->buf;
617  uint8_t pixel_width = (img->type == IMAGE_YUV422) ? 2 : 1;
618  uint16_t startx = from->x;
619  uint16_t starty = from->y;
620 
621  /* compute the distances in both directions */
622  int32_t delta_x = to->x - from->x;
623  int32_t delta_y = to->y - from->y;
624 
625  /* Compute the direction of the increment,
626  an increment of 0 means either a horizontal or vertical
627  line.
628  */
629  int8_t incx, incy;
630  if (delta_x > 0) { incx = 1; }
631  else if (delta_x == 0) { incx = 0; }
632  else { incx = -1; }
633 
634  if (delta_y > 0) { incy = 1; }
635  else if (delta_y == 0) { incy = 0; }
636  else { incy = -1; }
637 
638  /* determine which distance is greater */
639  uint16_t distance = 0;
640  delta_x = abs(delta_x);
641  delta_y = abs(delta_y);
642  if (delta_x > delta_y) { distance = delta_x * 20; }
643  else { distance = delta_y * 20; }
644 
645  /* draw the line */
646  for (uint16_t t = 0; /* starty >= 0 && */ starty < img->h && /* startx >= 0 && */ startx < img->w
647  && t <= distance + 1; t++) {
648  uint32_t buf_loc = img->w * pixel_width * starty + startx * pixel_width;
649  img_buf[buf_loc] = (t <= 3) ? 0 : color[0]; // u (or grayscale)
650 
651  if (img->type == IMAGE_YUV422) {
652  img_buf[buf_loc + 1] = color[1]; // y1
653 
654  if (startx + 1 < img->w) {
655  img_buf[buf_loc + 2] = (t <= 3) ? 0 : color[2]; // v
656  img_buf[buf_loc + 3] = color[3]; // y2
657  }
658  }
659 
660  xerr += delta_x;
661  yerr += delta_y;
662  if (xerr > distance) {
663  xerr -= distance;
664  startx += incx;
665  }
666  if (yerr > distance) {
667  yerr -= distance;
668  starty += incy;
669  }
670  }
671 }
unsigned short uint16_t
Definition: types.h:16
void image_gradients(struct image_t *input, struct image_t *dx, struct image_t *dy)
Calculate the gradients using the following matrix: [0 -1 0; -1 0 1; 0 1 0].
Definition: image.c:422
static uint32_t idx
static uint8_t dest[]
Definition: w5100.c:99
uint32_t buf_size
The buffer size.
Definition: image.h:52
image_type
Definition: image.h:35
void image_yuv422_downsample(struct image_t *input, struct image_t *output, uint16_t downsample)
Simplified high-speed low CPU downsample function without averaging downsample factor must be 1...
Definition: image.c:213
void pyramid_build(struct image_t *input, struct image_t *output_array, uint8_t pyr_level, uint8_t border_size)
This function populates given array of image_t structs with wanted number of padded pyramids based on...
Definition: image.c:337
uint32_t image_difference(struct image_t *img_a, struct image_t *img_b, struct image_t *diff)
Calculate the difference between two images and return the error This will only work with grayscale i...
Definition: image.c:478
void image_switch(struct image_t *a, struct image_t *b)
This will switch image *a and *b This is faster as image_copy because it doesn't copy the whole image...
Definition: image.c:97
void image_free(struct image_t *img)
Free the image.
Definition: image.c:63
void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
Create a new image.
Definition: image.c:38
Definition: image.h:43
Definition: image.h:66
void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *to)
Draw a pink line on the image.
Definition: image.c:600
void image_copy(struct image_t *input, struct image_t *output)
Copy an image from inut to output This will only work if the formats are the same.
Definition: image.c:77
void image_show_points(struct image_t *img, struct point_t *points, uint16_t points_cnt)
Show points in an image by coloring them through giving the pixels the maximum value.
Definition: image.c:552
uint32_t x
The x coordinate of the point.
Definition: image.h:58
void image_show_flow(struct image_t *img, struct flow_t *vectors, uint16_t points_cnt, uint8_t subpixel_factor)
Shows the flow from a specific point to a new point This works on YUV422 and Grayscale images...
Definition: image.c:577
void pyramid_next_level(struct image_t *input, struct image_t *output, uint8_t border_size)
This function takes previous padded pyramid level and outputs next level of pyramid without padding...
Definition: image.c:290
Image helper functions like resizing, color filter, converters...
int16_t flow_x
The x direction flow in subpixels.
Definition: image.h:68
uint16_t w
Image width.
Definition: image.h:45
unsigned long uint32_t
Definition: types.h:18
uint16_t h
Image height.
Definition: image.h:46
signed short int16_t
Definition: types.h:17
void image_add_border(struct image_t *input, struct image_t *output, uint8_t border_size)
This function adds padding to input image by mirroring the edge image elements.
Definition: image.c:245
void * buf
Image buffer (depending on the image_type)
Definition: image.h:53
struct point_t pos
The original position the flow comes from.
Definition: image.h:67
uint32_t y
The y coordinate of the point.
Definition: image.h:59
void image_to_grayscale(struct image_t *input, struct image_t *output)
Convert an image to grayscale.
Definition: image.c:116
Definition: image.h:57
void image_draw_line_color(struct image_t *img, struct point_t *from, struct point_t *to, uint8_t *color)
Draw a line on the image.
Definition: image.c:613
signed long int32_t
Definition: types.h:19
unsigned char uint8_t
Definition: types.h:14
struct timeval ts
The timestamp of creation.
Definition: image.h:47
UYVY format (uint16 per pixel)
Definition: image.h:36
void image_calculate_g(struct image_t *dx, struct image_t *dy, int32_t *g)
Calculate the G vector of an image gradient This is used for optical flow calculation.
Definition: image.c:446
signed char int8_t
Definition: types.h:15
An image gradient (int16 per pixel)
Definition: image.h:39
uint16_t image_yuv422_colorfilt(struct image_t *input, struct image_t *output, uint8_t y_m, uint8_t y_M, uint8_t u_m, uint8_t u_M, uint8_t v_m, uint8_t v_M)
Filter colors in an YUV422 image.
Definition: image.c:149
int16_t flow_y
The y direction flow in subpixels.
Definition: image.h:69
int32_t image_multiply(struct image_t *img_a, struct image_t *img_b, struct image_t *mult)
Calculate the multiplication between two images and return the error This will only work with image g...
Definition: image.c:516
void image_subpixel_window(struct image_t *input, struct image_t *output, struct point_t *center, uint32_t subpixel_factor, uint8_t border_size)
This outputs a subpixel window image in grayscale Currently only works with Grayscale images as input...
Definition: image.c:364
An JPEG encoded image (not per pixel encoded)
Definition: image.h:38
enum image_type type
The image type.
Definition: image.h:44