/* * EffecTV - Realtime Digital Video Effector * Copyright (C) 2001-2006 FUKUCHI Kentaro * * image.c: utilities for image processing. * */ #include #include #include "utils.h" /* * Collection of background subtraction functions */ /* checks only fake-Y value */ /* In these function Y value is treated as R*2+G*4+B. */ int image_set_threshold_y(int threshold) { int y_threshold = threshold * 7; /* fake-Y value is timed by 7 */ return y_threshold; } void image_bgset_y(RGB32 *background, const RGB32 *src, int video_area, int y_threshold) { int i; int R, G, B; const RGB32 *p; short *q; p = src; q = (short *)background; for(i=0; i>(16-1); G = ((*p)&0xff00)>>(8-2); B = (*p)&0xff; *q = (short)(R + G + B); p++; q++; } } void image_bgsubtract_y(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, int y_threshold) { int i; int R, G, B; const RGB32 *p; short *q; unsigned char *r; int v; p = src; q = (short *)background; r = diff; for(i=0; i>(16-1); G = ((*p)&0xff00)>>(8-2); B = (*p)&0xff; v = (R + G + B) - (int)(*q); *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24); p++; q++; r++; } /* The origin of subtraction function is; * diff(src, dest) = (abs(src - dest) > threshold) ? 0xff : 0; * * This functions is transformed to; * (threshold > (src - dest) > -threshold) ? 0 : 0xff; * * (v + threshold)>>24 is 0xff when v is less than -threshold. * (v - threshold)>>24 is 0xff when v is less than threshold. * So, ((v + threshold)>>24) | ((threshold - v)>>24) will become 0xff when * abs(src - dest) > threshold. */ } /* Background image is refreshed every frame */ void image_bgsubtract_update_y(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, int y_threshold) { int i; int R, G, B; const RGB32 *p; short *q; unsigned char *r; int v; p = src; q = (short *)background; r = diff; for(i=0; i>(16-1); G = ((*p)&0xff00)>>(8-2); B = (*p)&0xff; v = (R + G + B) - (int)(*q); *q = (short)(R + G + B); *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24); p++; q++; r++; } } /* checks each RGB value */ /* The range of r, g, b are [0..7] */ RGB32 image_set_threshold_RGB(int r, int g, int b) { unsigned char R, G, B; RGB32 rgb_threshold; R = G = B = 0xff; R = R<>8); b = b ^ 0xffffff; a = a ^ b; a = a & rgb_threshold; *r++ = (0 - a)>>24; } } void image_bgsubtract_update_RGB(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold) { int i; const RGB32 *p; RGB32 *q; unsigned a, b; unsigned char *r; p = src; q = background; r = diff; for(i=0; i>8); b = b ^ 0xffffff; a = a ^ b; a = a & rgb_threshold; *r++ = (0 - a)>>24; } } /* noise filter for subtracted image. */ void image_diff_filter(unsigned char *diff2, const unsigned char *diff, int width, int height) { int x, y; const unsigned char *src; unsigned char *dest; unsigned int count; unsigned int sum1, sum2, sum3; src = diff; dest = diff2 + width +1; for(y=1; y>24; src++; } dest += 2; } } /* Y value filters */ void image_y_over(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold) { int i; int R, G, B, v; unsigned char *p = diff; for(i = video_area; i>0; i--) { R = ((*src)&0xff0000)>>(16-1); G = ((*src)&0xff00)>>(8-2); B = (*src)&0xff; v = y_threshold - (R + G + B); *p = (unsigned char)(v>>24); src++; p++; } } void image_y_under(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold) { int i; int R, G, B, v; unsigned char *p = diff; for(i = video_area; i>0; i--) { R = ((*src)&0xff0000)>>(16-1); G = ((*src)&0xff00)>>(8-2); B = (*src)&0xff; v = (R + G + B) - y_threshold; *p = (unsigned char)(v>>24); src++; p++; } } /* tiny edge detection */ void image_edge(unsigned char *diff2, const RGB32 *src, int width, int height, int y_threshold) { int x, y; unsigned char *p, *q; int r, g, b; int ar, ag, ab; int w; p = (unsigned char *)src; q = diff2; w = width * sizeof(RGB32); for(y=0; y y_threshold) { *q = 255; } else { *q = 0; } q++; p += 4; } p += 4; *q++ = 0; } memset(q, 0, width); } /* horizontal flipping */ void image_hflip(const RGB32 *src, RGB32 *dest, int width, int height) { int x, y; src += width - 1; for(y=0; y