65 if (img->
buf != NULL) {
86 memcpy(&output->
ts, &input->
ts,
sizeof(
struct timeval));
101 memcpy(&old_a, a,
sizeof(
struct image_t));
104 memcpy(a, b,
sizeof(
struct image_t));
107 memcpy(b, &old_a,
sizeof(
struct image_t));
123 memcpy(&output->
ts, &input->
ts,
sizeof(
struct timeval));
126 for (
int y = 0; y < output->
h; y++) {
127 for (
int x = 0; x < output->
w; x++) {
157 memcpy(&output->
ts, &input->
ts,
sizeof(
struct timeval));
160 for (
uint16_t y = 0; y < output->
h; y++) {
161 for (
uint16_t x = 0; x < output->
w; x += 2) {
179 char u = source[0] - 127;
217 uint16_t pixelskip = (downsample - 1) * 2;
220 memcpy(&output->
ts, &input->
ts,
sizeof(
struct timeval));
223 for (
uint16_t y = 0; y < output->
h; y++) {
224 for (
uint16_t x = 0; x < output->
w; x += 2) {
234 source += (downsample - 1) * input->
w * 2;
254 uint16_t subpixel_w = input->
w * subpixel_factor;
255 uint16_t subpixel_h = input->
h * subpixel_factor;
258 for (
uint16_t i = 0; i < output->
w; i++) {
259 for (
uint16_t j = 0; j < output->
h; j++) {
261 uint16_t x = center->
x + (i - half_window) * subpixel_factor;
262 uint16_t y = center->
y + (j - half_window) * subpixel_factor;
263 BoundUpper(x, subpixel_w);
264 BoundUpper(y, subpixel_h);
267 uint16_t orig_x = x / subpixel_factor;
268 uint16_t orig_y = y / subpixel_factor;
271 uint16_t tl_x = orig_x * subpixel_factor;
272 uint16_t tl_y = orig_y * subpixel_factor;
275 if (tl_x == x && tl_y == y) {
276 output_buf[output->
w * j + i] = input_buf[input->
w * orig_y + orig_x];
283 uint32_t blend = (subpixel_factor - alpha_x) * (subpixel_factor - alpha_y) * input_buf[input->
w * orig_y + orig_x];
284 blend += alpha_x * (subpixel_factor - alpha_y) * input_buf[input->
w * orig_y + (orig_x + 1)];
285 blend += (subpixel_factor - alpha_x) * alpha_y * input_buf[input->
w * (orig_y + 1) + orig_x];
286 blend += alpha_x * alpha_y * input_buf[input->
w * (orig_y + 1) + (orig_x + 1)];
289 output_buf[output->
w * j + i] = blend / (subpixel_factor * subpixel_factor);
310 for (
uint16_t x = 1; x < input->
w - 1; x++) {
311 for (
uint16_t y = 1; y < input->
h - 1; y++) {
312 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];
313 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];
327 int32_t sum_dxx = 0, sum_dxy = 0, sum_dyy = 0;
336 sum_dxx += ((
int32_t)dx_buf[y * dx->
w + x] * dx_buf[y * dx->
w + x]);
337 sum_dxy += ((
int32_t)dx_buf[y * dx->
w + x] * dy_buf[y * dy->
w + x]);
338 sum_dyy += ((
int32_t)dy_buf[y * dy->
w + x] * dy_buf[y * dy->
w + x]);
343 g[0] = sum_dxx / 255;
344 g[1] = sum_dxy / 255;
346 g[3] = sum_dyy / 255;
372 for (
uint16_t x = 0; x < img_b->
w; x++) {
373 for (
uint16_t y = 0; y < img_b->
h; y++) {
374 int16_t diff_c = img_a_buf[(y + 1) * img_a->
w + (x + 1)] - img_b_buf[y * img_b->
w + x];
375 sum_diff2 += diff_c * diff_c;
378 if (diff_buf != NULL) {
379 diff_buf[y * diff->
w + x] = diff_c;
408 for (
uint16_t x = 0; x < img_a->
w; x++) {
409 for (
uint16_t y = 0; y < img_a->
h; y++) {
410 int16_t mult_c = img_a_buf[y * img_a->
w + x] * img_b_buf[y * img_b->
w + x];
414 if (mult_buf != NULL) {
415 mult_buf[y * mult->
w + x] = mult_c;
437 for (
int i = 0; i < points_cnt; i++) {
438 uint32_t idx = pixel_width * points[i].
y * img->
w + points[i].
x * pixel_width;
459 for (
uint16_t i = 0; i < points_cnt; i++) {
462 vectors[i].
pos.
x / subpixel_factor,
463 vectors[i].
pos.
y / subpixel_factor
466 (vectors[i].
pos.
x + vectors[i].
flow_x) / subpixel_factor,
467 (vectors[i].pos.y + vectors[i].
flow_y) / subpixel_factor
481 int xerr = 0, yerr = 0;
496 if (delta_x > 0) { incx = 1; }
497 else if (delta_x == 0) { incx = 0; }
500 if (delta_y > 0) { incy = 1; }
501 else if (delta_y == 0) { incy = 0; }
506 delta_x = abs(delta_x);
507 delta_y = abs(delta_y);
508 if (delta_x > delta_y) { distance = delta_x * 20; }
509 else { distance = delta_y * 20; }
512 for (
uint16_t t = 0; starty < img->
h && startx < img->
w && t <= distance + 1; t++) {
513 img_buf[img->
w * pixel_width * starty + startx * pixel_width] = (t <= 3) ? 0 : 255;
516 img_buf[img->
w * pixel_width * starty + startx * pixel_width + 1] = 255;
518 if (startx + 1 < img->
w) {
519 img_buf[img->
w * pixel_width * starty + startx * pixel_width + 2] = (t <= 3) ? 0 : 255;
520 img_buf[img->
w * pixel_width * starty + startx * pixel_width + 3] = 255;
526 if (xerr > distance) {
530 if (yerr > distance) {
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].
uint16_t x
The x coordinate of the point.
uint32_t buf_size
The buffer size.
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...
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...
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...
void image_free(struct image_t *img)
Free the image.
void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
Create a new image.
void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *to)
Draw a line on the image.
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.
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.
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...
Image helper functions like resizing, color filter, converters...
int16_t flow_x
The x direction flow in subpixels.
void * buf
Image buffer (depending on the image_type)
struct point_t pos
The original position the flow comes from.
void image_to_grayscale(struct image_t *input, struct image_t *output)
Convert an image to grayscale.
struct timeval ts
The timestamp of creation.
UYVY format (uint16 per pixel)
uint16_t y
The y coordinate of the point.
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.
void image_subpixel_window(struct image_t *input, struct image_t *output, struct point_t *center, uint16_t subpixel_factor)
This outputs a subpixel window image in grayscale Currently only works with Grayscale images as input...
An image gradient (int16 per pixel)
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.
int16_t flow_y
The y direction flow in subpixels.
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...
An JPEG encoded image (not per pixel encoded)
enum image_type type
The image type.