LLIPS  rev33
Light Library for Image ProcesS
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
llips_motiondetect.c
Go to the documentation of this file.
1 /********************************************/
8 /* ***************************************************************/
9 /* * Includes */
10 /* ***************************************************************/
11 #include "llips_includes.h"
12 
13 /* ***************************************************************/
14 /* * Global variables */
15 /* ***************************************************************/
16 
17 /* ***************************************************************/
18 /* * Functions */
19 /* ***************************************************************/
20 
21 
22 /********************************************/
42 CPU_CHAR search_diff(CPU_INT16U tolerance,CPU_INT16U quantity, t_img * img_in1,t_img * img_in2,t_img * img_out,t_area * change_img)
43 {
44  CPU_CHAR ret = NO_DIFF;
45  CPU_INT16S i,j;
46  CPU_INT16U raw_tolerance,raw_quantity;
47  CPU_INT16U quantity_of_diff_pixel = 0;
48 
49  // calculte raw tolerance and quantity
50  raw_quantity = ((img_in1->he * img_in1->wi)*quantity)/1000;
51  raw_tolerance = ((PIXEL_8bit_RANGE)*tolerance)/100;
52 
53  if((img_in1->he == img_in2->he) && (img_in1->wi == img_in2->wi))
54  {
55  init_area(change_img,img_in1->wi,img_in1->he);
56 
57  //Write Header
58  for(i=0;i<img_in2->FileHeader_size;i++)
59  {
60  img_out->FileHeader[i] = img_in2->FileHeader[i];
61  }
62  img_out->signature = img_in2->signature;
63  img_out->depth = img_in2->depth;
64  img_out->wi = img_in2->wi;
65  img_out->he = img_in2->he;
66  img_out->FileHeader_size = img_in2->FileHeader_size;
67 
68  //same size
69  for(i=0;i< img_in1->he ;i++)
70  {
71  for(j=0 ; j< img_in1->wi ;j++)
72  {
73  img_out->Blue[i][j] = abs((CPU_INT16S)(img_in1->Blue[i][j]) - (CPU_INT16S)(img_in2->Blue[i][j]));
74  if (img_out->Blue[i][j] > raw_tolerance)
75  {
76  ret |= DIFF_BLUE;
77  }
78  img_out->Green[i][j] = abs((CPU_INT16S)(img_in1->Green[i][j]) - (CPU_INT16S)(img_in2->Green[i][j]));
79  if (img_out->Green[i][j] > raw_tolerance)
80  {
81  ret |= DIFF_GREEN;
82  }
83  img_out->Red[i][j] = abs((CPU_INT16S)(img_in1->Red[i][j]) - (CPU_INT16S)(img_in2->Red[i][j]));
84  if (img_out->Red[i][j] > raw_tolerance)
85  {
86  ret |= DIFF_RED;
87  }
88 
89  if ((img_out->Blue[i][j] > raw_tolerance) || (img_out->Green[i][j] > raw_tolerance) || (img_out->Red[i][j] > raw_tolerance))
90  {
91  img_out->Green[i][j] = (CPU_CHAR)(CPU_FP32)img_in2->Blue[i][j]*2.5;
92  img_out->Blue[i][j] = img_in2->Blue[i][j]/2;
93  img_out->Red[i][j] = img_in2->Red[i][j]/2;
94  quantity_of_diff_pixel ++;
95 
96  /* identify area of change */
97  change_img->BotLeft.x = mini(change_img->BotLeft.x,j);
98  change_img->BotLeft.y = mini(change_img->BotLeft.y,i);
99  change_img->BotRight.x = maxi(change_img->BotRight.x,j);
100  change_img->BotRight.y = mini(change_img->BotRight.y,i);
101  change_img->TopLeft.x = mini(change_img->TopLeft.x,j);
102  change_img->TopLeft.y = maxi(change_img->TopLeft.y,i);
103  change_img->TopRight.x = maxi(change_img->TopRight.x,j);
104  change_img->TopRight.y = maxi(change_img->TopRight.y,i);
105 
106  }else
107  {
108  img_out->Green[i][j] = img_in2->Green[i][j];
109  img_out->Blue[i][j] = img_in2->Blue[i][j];
110  img_out->Red[i][j] = img_in2->Red[i][j];
111  }
112  }
113  }
114  }else
115  {
116  // size different
117  ret |= DIFF_SIZE;
118  }
119  if (quantity_of_diff_pixel > raw_quantity)
120  {
121  ret |= DIFF_HIGH_QUANTITY;
122  }
123 
124  highlight_area(img_out,change_img,SetRGB(255,0,0));
125 
126  return ret;
127 }
128 
129 
130 /********************************************/
141 t_vect evaluate_move(t_img * p_img_base,t_img * p_img_target,t_area area_1,t_area area_2, t_vect * p_movement_origin)
142 {
143  t_vect ret = {0};
144  t_pixel temporary_pixel_1,temporary_pixel_2,temporary_pixel_3;
145  t_area area_1_center,area_2_center;
146  CPU_INT16U i;
147 
148  //Write Header for target img, base on base img data
149  for(i=0;i<p_img_base->FileHeader_size;i++)
150  {
151  p_img_target->FileHeader[i] = p_img_base->FileHeader[i];
152  }
153  p_img_target->signature = p_img_base->signature;
154  p_img_target->depth = p_img_base->depth;
155  p_img_target->wi = p_img_base->wi;
156  p_img_target->he = p_img_base->he;
157  p_img_target->FileHeader_size = p_img_base->FileHeader_size;
158 
159 
160  temporary_pixel_1.x = (area_1.BotLeft.x + area_1.TopRight.x)/2 ;
161  temporary_pixel_1.y = (area_1.BotLeft.y + area_1.TopRight.y)/2 ;
162 
163  temporary_pixel_2.x = (area_2.BotLeft.x + area_2.TopRight.x)/2 ;
164  temporary_pixel_2.y = (area_2.BotLeft.y + area_2.TopRight.y)/2 ;
165 
166  temporary_pixel_3.x = p_img_base->wi / 2;
167  temporary_pixel_3.y = p_img_base->he / 2;
168 
169  area_1_center.TopLeft.x = temporary_pixel_1.x - 1;
170  area_1_center.TopLeft.y = temporary_pixel_1.y + 1;
171  area_1_center.TopRight.x = temporary_pixel_1.x + 1;
172  area_1_center.TopRight.y = temporary_pixel_1.y + 1;
173  area_1_center.BotLeft.x = temporary_pixel_1.x - 1;
174  area_1_center.BotLeft.y = temporary_pixel_1.y - 1;
175  area_1_center.BotRight.x = temporary_pixel_1.x + 1;
176  area_1_center.BotRight.y = temporary_pixel_1.y - 1;
177 
178  area_2_center.TopLeft.x = temporary_pixel_2.x - 1;
179  area_2_center.TopLeft.y = temporary_pixel_2.y + 1;
180  area_2_center.TopRight.x = temporary_pixel_2.x + 1;
181  area_2_center.TopRight.y = temporary_pixel_2.y + 1;
182  area_2_center.BotLeft.x = temporary_pixel_2.x - 1;
183  area_2_center.BotLeft.y = temporary_pixel_2.y - 1;
184  area_2_center.BotRight.x = temporary_pixel_2.x + 1;
185  area_2_center.BotRight.y = temporary_pixel_2.y - 1;
186 
187  highlight_area(p_img_target,&area_1,SetRGB(255,0,0));
188  highlight_area(p_img_target,&area_1_center,SetRGB(255,0,0));
189  highlight_area(p_img_target,&area_2,SetRGB(0,255,0));
190  highlight_area(p_img_target,&area_2_center,SetRGB(0,255,0));
191 
192  ret = pixels_to_vector(temporary_pixel_1,temporary_pixel_2);
193  *p_movement_origin = pixels_to_vector(temporary_pixel_3,temporary_pixel_1);
194 
195  return ret;
196 }
197 
198 
199 /********************************************/
211 CPU_CHAR search_diff_x(CPU_INT16U tolerance,CPU_INT16U quantity, t_img * img_in1,t_img * img_in2,t_img * img_out,t_area * change_img)
212 {
213  CPU_CHAR ret = NO_DIFF;
214  CPU_INT16S i,j,areasize;
215  CPU_INT16U raw_tolerance,raw_quantity;
216  CPU_INT16U quantity_of_diff_pixel = 0,module=0;
217  t_pixel area1,area2;
218  t_area area_pic2;
219  CPU_INT16U maxmodule=0;
220 
221  // calculte raw tolerance and quantity
222  raw_quantity = ((img_in1->he * img_in1->wi)*quantity)/1000;
223  raw_tolerance = ((PIXEL_8bit_RANGE)*tolerance)/100;
224 
225  if((img_in1->he == img_in2->he) && (img_in1->wi == img_in2->wi))
226  {
227  init_area(change_img,img_in1->wi,img_in1->he);
228 
229  //Write Header
230  for(i=0;i<img_in2->FileHeader_size;i++)
231  {
232  img_out->FileHeader[i] = img_in2->FileHeader[i];
233  }
234  img_out->signature = img_in2->signature;
235  img_out->depth = img_in2->depth;
236  img_out->wi = img_in2->wi;
237  img_out->he = img_in2->he;
238  img_out->FileHeader_size = img_in2->FileHeader_size;
239 
240  //same size
241  for(i=0;i< img_in1->he ;i++)
242  {
243  for(j=0 ; j< img_in1->wi ;j++)
244  {
245  img_out->Blue[i][j] = abs((CPU_INT16S)(img_in1->Blue[i][j]) - (CPU_INT16S)(img_in2->Blue[i][j]));
246  if (img_out->Blue[i][j] > raw_tolerance)
247  {
248  ret |= DIFF_BLUE;
249  }
250  img_out->Green[i][j] = abs((CPU_INT16S)(img_in1->Green[i][j]) - (CPU_INT16S)(img_in2->Green[i][j]));
251  if (img_out->Green[i][j] > raw_tolerance)
252  {
253  ret |= DIFF_GREEN;
254  }
255  img_out->Red[i][j] = abs((CPU_INT16S)(img_in1->Red[i][j]) - (CPU_INT16S)(img_in2->Red[i][j]));
256  if (img_out->Red[i][j] > raw_tolerance)
257  {
258  ret |= DIFF_RED;
259  }
260 
261  if ((img_out->Blue[i][j] > raw_tolerance) || (img_out->Green[i][j] > raw_tolerance) || (img_out->Red[i][j] > raw_tolerance))
262  {
263  img_out->Green[i][j] = (CPU_CHAR)(CPU_FP32)img_in2->Blue[i][j]*2.5;
264  img_out->Blue[i][j] = 0;//img_in2->Blue[i][j]/2;
265  img_out->Red[i][j] = 0;//img_in2->Red[i][j]/2;
266  quantity_of_diff_pixel ++;
267 
268  if(((i>15)&&(j>15))&&((i<img_in2->he)&&(j<img_in2->wi)))
269  {
270  areasize = 15;
271  change_img->BotLeft.x = j - areasize /2 ;
272  change_img->BotLeft.y = i + areasize /2 ;
273  change_img->BotRight.x = j + areasize /2 ;
274  change_img->BotRight.y = i - areasize /2 ;
275  change_img->TopLeft.x = j + areasize /2 ;
276  change_img->TopLeft.y = i - areasize /2 ;
277  change_img->TopRight.x = j - areasize /2 ;
278  change_img->TopRight.y = i + areasize /2 ;
279  area1.x = j;
280  area1.y = i;
281  area2.x = 0;
282  area2.y = 0;
283  area2 = look_for_match(img_in1,img_in2,areasize,area1,raw_tolerance);
284  if ((area2.x != 0)&&(area2.y != 0))
285  {
286  module = vectormodule(pixels_to_vector(area1,area2));
287  maxmodule = maxi(module,maxmodule);
288  areasize = 2;
289  area_pic2.BotLeft.x = area2.x - areasize /2 ;
290  area_pic2.BotLeft.y = area2.y + areasize /2 ;
291  area_pic2.BotRight.x = area2.x + areasize /2 ;
292  area_pic2.BotRight.y = area2.y - areasize /2 ;
293  area_pic2.TopLeft.x = area2.x + areasize /2 ;
294  area_pic2.TopLeft.y = area2.y - areasize /2 ;
295  area_pic2.TopRight.x = area2.x - areasize /2 ;
296  area_pic2.TopRight.y = area2.y + areasize /2 ;
297  //highlight_area(img_out,change_img,SetRGB(255,0,0));
298  highlight_area(img_out,&area_pic2,SetRGB(module*6,0,0));
299  }
300 
301  }
302 
303 
304  }else
305  {
306  img_out->Green[i][j] = 0;
307  img_out->Blue[i][j] = 0;
308  img_out->Red[i][j] = 0;
309  }
310  }
311  }
312  printf("maxmodule : %d\n",maxmodule);
313  }else
314  {
315  // size different
316  ret |= DIFF_SIZE;
317  }
318  if (quantity_of_diff_pixel > raw_quantity)
319  {
320  ret |= DIFF_HIGH_QUANTITY;
321  }
322 
323 
324  return ret;
325 }
326 
327 /********************************************/
338 t_pixel look_for_match(t_img * img_in1,t_img * img_in2,CPU_INT16U areasize,t_pixel area_from_1,CPU_INT16U raw_tolerance)
339 {
340  t_pixel area_to_2;
341  CPU_INT16U i,j;
342  CPU_INT08U ** table_src,** table_dest;
343  CPU_INT16S range_i = 10,offset_i;
344  CPU_INT16S range_j = 32,offset_j;
345  CPU_BOOLEAN match = FALSE;
346  area_to_2.x = 0;
347  area_to_2.y = 0;
348  table_src = createTableINT08U(areasize, areasize);
349  table_dest = createTableINT08U(areasize, areasize);
350 
351  // init area of the first image
352  for(i=0;i< areasize ;i++)
353  {
354  for(j=0 ; j< areasize ;j++)
355  {
356  table_src[i][j] = img_in1->Green[i+(area_from_1.y - areasize / 2)][j+(area_from_1.x - areasize / 2)];
357  }
358  }
359 
360  offset_i = 0;
361  offset_j = 0;
362  for( offset_i=(0-(range_i/2)); offset_i< (range_i/2) ;offset_i++)
363  {
364  for(offset_j=0;offset_j> (0 - range_j) ;offset_j--)
365  {
366  // init area of the second image
367  for(i=0;i< areasize ;i++)
368  {
369  for(j=0 ; j< areasize ;j++)
370  {
371  table_dest[i][j] = img_in2->Green[i+(area_from_1.y - areasize / 2)+offset_i][j+(area_from_1.x - areasize / 2)+offset_j];
372  }
373  }
374 
375  match = TRUE;
376  for(i=0;i< areasize ;i++)
377  {
378  for(j=0 ; j< areasize ;j++)
379  {
380  if ((abs(table_dest[i][j] - table_src[i][j]))>(raw_tolerance*3)/2)
381  {
382  match = FALSE;
383  }
384  }
385  }
386  if(match == TRUE)
387  {
388  area_to_2.x = area_from_1.x + offset_j;
389  area_to_2.y = area_from_1.y + offset_i;
390  }else
391  {
392 
393  }
394  if(match == TRUE)break;
395  }
396  if(match == TRUE)break;
397  }
398 
399  return area_to_2;
400 }
401 
CPU_VOID init_area(t_area *area, CPU_INT16U maxwidth, CPU_INT16U maxheight)
Initialize an area from 0,0 to given values.
t_pixel look_for_match(t_img *img_in1, t_img *img_in2, CPU_INT16U areasize, t_pixel area_from_1, CPU_INT16U raw_tolerance)
Try to find a correspondance from an area from image 1 in image 2.
CPU_INT16U y
Definition: llips_type.h:51
#define DIFF_RED
Definition: llips_general.h:60
CPU_INT16U signature
Definition: llips_type.h:35
float CPU_FP32
Definition: llips_type.h:29
#define SetRGB(r, g, b)
Definition: llips_general.h:83
CPU_INT08U FileHeader_size
Definition: llips_type.h:44
t_pixel BotRight
Definition: llips_type.h:63
CPU_INT32U maxi(CPU_INT32U a, CPU_INT32U b)
compare two CPU_INT32U to find the biggest
t_pixel BotLeft
Definition: llips_type.h:62
CPU_CHAR search_diff(CPU_INT16U tolerance, CPU_INT16U quantity, t_img *img_in1, t_img *img_in2, t_img *img_out, t_area *change_img)
Search for difference between two images, using given tolerance and quantity change criteria...
CPU_INT16U vectormodule(t_vect vect)
Give module of a vector, in "pixel".
CPU_INT16U depth
Definition: llips_type.h:36
t_vect pixels_to_vector(t_pixel pix1, t_pixel pix2)
Convert two pixel into a vector.
t_pixel TopLeft
Definition: llips_type.h:64
#define DIFF_HIGH_QUANTITY
Definition: llips_general.h:61
#define DIFF_GREEN
Definition: llips_general.h:59
#define DIFF_SIZE
Definition: llips_general.h:57
Global include file for LLIPS.
CPU_INT32U wi
Definition: llips_type.h:37
unsigned char CPU_CHAR
Definition: llips_type.h:21
#define NO_DIFF
Definition: llips_general.h:56
CPU_VOID highlight_area(t_img *img, t_area *area, CPU_INT32U RGB)
Draw a rectangular area on image in a given color.
CPU_CHAR search_diff_x(CPU_INT16U tolerance, CPU_INT16U quantity, t_img *img_in1, t_img *img_in2, t_img *img_out, t_area *change_img)
Search for difference between two images, using given tolerance and quantity change criteria...
unsigned char CPU_BOOLEAN
Definition: llips_type.h:22
CPU_INT08U ** Red
Definition: llips_type.h:41
#define TRUE
Definition: llips_cfg.h:22
CPU_INT08U ** createTableINT08U(CPU_INT16S nbLin, CPU_INT16S nbCol)
Allocate memory for a CPU_INT08U 2D table.
signed short CPU_INT16S
Definition: llips_type.h:26
CPU_INT32U mini(CPU_INT32U a, CPU_INT32U b)
Compare two CPU_INT32U to find the smallest.
CPU_INT08U FileHeader[MAX_HEADER_size]
Definition: llips_type.h:43
CPU_INT16U x
Definition: llips_type.h:50
t_pixel TopRight
Definition: llips_type.h:65
CPU_INT08U ** Blue
Definition: llips_type.h:39
#define DIFF_BLUE
Definition: llips_general.h:58
unsigned short CPU_INT16U
Definition: llips_type.h:25
CPU_INT08U ** Green
Definition: llips_type.h:40
#define PIXEL_8bit_RANGE
Definition: llips_general.h:29
unsigned char CPU_INT08U
Definition: llips_type.h:23
CPU_INT32U he
Definition: llips_type.h:38
t_vect evaluate_move(t_img *p_img_base, t_img *p_img_target, t_area area_1, t_area area_2, t_vect *p_movement_origin)
Evaluate mouvement direction between three sequencial images that have been previously processed by s...
#define FALSE
Definition: llips_cfg.h:23