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
= (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 unsigned char *p
, *q
;
264 p
= (unsigned char *)src
;
266 w
= width
* sizeof(RGB32
);
268 for(y
=0; y
<height
- 1; y
++) {
269 for(x
=0; x
<width
- 1; x
++) {
277 ag
+= abs(g
- p
[w
+1]);
278 ar
+= abs(r
- p
[w
+2]);
280 if(b
> y_threshold
) {
294 /* horizontal flipping */
295 void image_hflip(const RGB32
*src
, RGB32
*dest
, int width
, int height
)
300 for(y
=0; y
<height
; y
++) {
301 for(x
=0; x
<width
; x
++) {