2 * EffecTV - Realtime Digital Video Effector
3 * Copyright (C) 2001-2006 FUKUCHI Kentaro
5 * image.c: utilities for image processing.
15 * Collection of background subtraction functions
18 /* checks only fake-Y value */
19 /* In these function Y value is treated as R*2+G*4+B. */
21 int image_set_threshold_y(int threshold)
23 int y_threshold = threshold * 7; /* fake-Y value is timed by 7 */
28 void image_bgset_y(RGB32 *background, const RGB32 *src, int video_area, int y_threshold)
36 q = (short *)background;
37 for(i=0; i<video_area; i++) {
38 /* FIXME: endianess */
40 R = ((*p)&0xff0000)>>(16-1);
41 G = ((*p)&0xff00)>>(8-2);
43 *q = (short)(R + G + B);
49 void image_bgsubtract_y(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, int y_threshold)
59 q = (const short *)background;
61 for(i=0; i<video_area; i++) {
62 /* FIXME: endianess */
64 R = ((*p)&0xff0000)>>(16-1);
65 G = ((*p)&0xff00)>>(8-2);
67 v = (R + G + B) - (int)(*q);
68 *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24);
75 /* The origin of subtraction function is;
76 * diff(src, dest) = (abs(src - dest) > threshold) ? 0xff : 0;
78 * This functions is transformed to;
79 * (threshold > (src - dest) > -threshold) ? 0 : 0xff;
81 * (v + threshold)>>24 is 0xff when v is less than -threshold.
82 * (v - threshold)>>24 is 0xff when v is less than threshold.
83 * So, ((v + threshold)>>24) | ((threshold - v)>>24) will become 0xff when
84 * abs(src - dest) > threshold.
88 /* Background image is refreshed every frame */
89 void image_bgsubtract_update_y(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, int y_threshold)
99 q = (short *)background;
101 for(i=0; i<video_area; i++) {
102 /* FIXME: endianess */
104 R = ((*p)&0xff0000)>>(16-1);
105 G = ((*p)&0xff00)>>(8-2);
107 v = (R + G + B) - (int)(*q);
108 *q = (short)(R + G + B);
109 *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24);
117 /* checks each RGB value */
119 /* The range of r, g, b are [0..7] */
120 RGB32 image_set_threshold_RGB(int r, int g, int b)
122 unsigned char R, G, B;
129 rgb_threshold = (RGB32)(R<<16 | G<<8 | B);
131 return rgb_threshold;
134 void image_bgset_RGB(RGB32 *background, const RGB32 *src, int video_area)
140 for(i=0; i<video_area; i++) {
141 *p++ = (*src++) & 0xfefefe;
145 void image_bgsubtract_RGB(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold)
155 for(i=0; i<video_area; i++) {
156 a = (*p++)|0x1010100;
163 a = a & rgb_threshold;
168 void image_bgsubtract_update_RGB(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold)
179 for(i=0; i<video_area; i++) {
188 a = a & rgb_threshold;
193 /* noise filter for subtracted image. */
194 void image_diff_filter(unsigned char *diff2, const unsigned char *diff, int width, int height)
197 const unsigned char *src;
200 unsigned int sum1, sum2, sum3;
203 dest = diff2 + width +1;
204 for(y=1; y<height-1; y++) {
205 sum1 = src[0] + src[width] + src[width*2];
206 sum2 = src[1] + src[width+1] + src[width*2+1];
208 for(x=1; x<width-1; x++) {
209 sum3 = src[0] + src[width] + src[width*2];
210 count = sum1 + sum2 + sum3;
213 *dest++ = (0xff*3 - count)>>24;
220 /* Y value filters */
221 void image_y_over(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold)
225 unsigned char *p = diff;
227 for(i = video_area; i>0; i--) {
228 R = ((*src)&0xff0000)>>(16-1);
229 G = ((*src)&0xff00)>>(8-2);
231 v = y_threshold - (R + G + B);
232 *p = (unsigned char)(v>>24);
238 void image_y_under(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold)
242 unsigned char *p = diff;
244 for(i = video_area; i>0; i--) {
245 R = ((*src)&0xff0000)>>(16-1);
246 G = ((*src)&0xff00)>>(8-2);
248 v = (R + G + B) - y_threshold;
249 *p = (unsigned char)(v>>24);
255 /* tiny edge detection */
256 void image_edge(unsigned char *diff2, const RGB32 *src, int width, int height, int y_threshold)
259 const unsigned char *p;
265 p = (const unsigned char *)src;
267 w = width * sizeof(RGB32);
269 for(y=0; y<height - 1; y++) {
270 for(x=0; x<width - 1; x++) {
278 ag += abs(g - p[w+1]);
279 ar += abs(r - p[w+2]);
281 if(b > y_threshold) {
295 /* horizontal flipping */
296 void image_hflip(const RGB32 *src, RGB32 *dest, int width, int height)
301 for(y=0; y<height; y++) {
302 for(x=0; x<width; x++) {