Fawkes API  Fawkes Development Version
imagediff.cpp
1 
2 /***************************************************************************
3  * imagediff.cpp - check images if they are different
4  *
5  * Generated: Tue Jun 06 10:22:49 2006
6  * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <fvutils/statistical/imagediff.h>
25 #include <fvutils/color/yuv.h>
26 
27 #include <cstdlib>
28 
29 namespace firevision {
30 #if 0 /* just to make Emacs auto-indent happy */
31 }
32 #endif
33 
34 /** @class ImageDiff <fvutils/statistical/imagediff.h>
35  * Image difference checker.
36  * @author Tim Niemueller
37  */
38 
39 /** Constructor.
40  * @param scanline_model scanlinemodel to use, if null all pixels
41  * are compared.
42  */
44 {
45  this->scanline_model = scanline_model;
46 }
47 
48 
49 /** Constructor.
50  * Use this constructor to compare all pixels.
51  */
53 {
54  scanline_model = NULL;
55 }
56 
57 
58 /** Destructor. */
60 {
61 }
62 
63 
64 /** Set first buffer.
65  * @param yuv422planar_buffer buffer
66  * @param width image width in pixels
67  * @param height image height in pixels
68  */
69 void
70 ImageDiff::setBufferA(unsigned char *yuv422planar_buffer,
71  unsigned int width, unsigned int height)
72 {
73  buffer_a = yuv422planar_buffer;
74  width_a = width;
75  height_a = height;
76 }
77 
78 
79 /** Set second buffer.
80  * @param yuv422planar_buffer buffer
81  * @param width image width in pixels
82  * @param height image height in pixels
83  */
84 void
85 ImageDiff::setBufferB(unsigned char *yuv422planar_buffer,
86  unsigned int width, unsigned int height)
87 {
88  buffer_b = yuv422planar_buffer;
89  width_b = width;
90  height_b = height;
91 }
92 
93 
94 /** Check if images are different.
95  * This method will compare the two images. If any pixel marked by
96  * the scanline or any pixel at all if no scanline model is given
97  * differ the images are considered to be different. The same applies
98  * if any buffer is unset or the widths or heights are not the same.
99  * @return true if images are different, false otherwise
100  */
101 bool
103 {
104  if ( (buffer_a == NULL) && (buffer_b == NULL) ) return false;
105  if ( (buffer_a == NULL) && (buffer_b != NULL) ) return true;
106  if ( (buffer_a != NULL) && (buffer_b == NULL) ) return true;
107  if ( (width_a != width_b) || (height_a != height_b) ) return true;
108 
109  if ( scanline_model != NULL ) {
110  // use the supplied scanline model
111 
112  unsigned int x, y;
113  unsigned char y_a, u_a, v_a, y_b, u_b, v_b;
114 
115  scanline_model->reset();
116  while (! scanline_model->finished() ) {
117  x = (*scanline_model)->x;
118  y = (*scanline_model)->y;
119 
120  YUV422_PLANAR_YUV(buffer_a, width_a, height_a, x, y, y_a, u_a, v_a);
121  YUV422_PLANAR_YUV(buffer_b, width_b, height_b, x, y, y_b, u_b, v_b);
122 
123  if ( (y_a != y_b) || (u_a != u_b) || (v_a != v_b) ) {
124  return true;
125  }
126  }
127  } else {
128  // no scanline model, check every single pixel
129 
130  unsigned char *ypa = buffer_a;
131  unsigned char *ypb = buffer_b;
132 
133  for ( unsigned int i = 0; i < (width_a * height_a); ++i) {
134  if ( *ypa != *ypb ) {
135  return true;
136  }
137  ++ypa;
138  ++ypb;
139  }
140  }
141 
142  return false;
143 }
144 
145 
146 /** Number of differing pixels.
147  * Executes the same routine as different(). But instead of just saying that
148  * the images are different will tell how many pixels differ.
149  * @return number of different pixels
150  */
151 unsigned int
153 {
154  if ( (buffer_a == NULL) && (buffer_b == NULL) ) return 0;
155  if ( (buffer_a == NULL) && (buffer_b != NULL) ) return (width_b * height_b);
156  if ( (buffer_a != NULL) && (buffer_b == NULL) ) return (width_a * height_a);
157  if ( (width_a != width_b) || (height_a != height_b) ) {
158  return std::abs((long)width_a - (long)width_b) * std::abs((long)height_a - (long)height_b);
159  }
160 
161  unsigned int num = 0;
162  if ( scanline_model != NULL ) {
163  // use the supplied scanline model
164 
165  unsigned int x, y;
166  unsigned char y_a, u_a, v_a, y_b, u_b, v_b;
167 
168  scanline_model->reset();
169  while (! scanline_model->finished() ) {
170  x = (*scanline_model)->x;
171  y = (*scanline_model)->y;
172 
173  YUV422_PLANAR_YUV(buffer_a, width_a, height_a, x, y, y_a, u_a, v_a);
174  YUV422_PLANAR_YUV(buffer_b, width_b, height_b, x, y, y_b, u_b, v_b);
175 
176  if ( (y_a != y_b) || (u_a != u_b) || (v_a != v_b) ) {
177  ++num;
178  }
179  }
180  } else {
181  // no scanline model, check every single pixel
182 
183  unsigned char *ypa = buffer_a;
184  unsigned char *ypb = buffer_b;
185 
186  for ( unsigned int i = 0; i < (width_a * height_a); ++i) {
187  if ( *ypa++ != *ypb++ ) ++num;
188  }
189  }
190  return num;
191 }
192 
193 } // end namespace firevision
unsigned int numDifferingPixels()
Number of differing pixels.
Definition: imagediff.cpp:152
ImageDiff()
Constructor.
Definition: imagediff.cpp:52
void setBufferA(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set first buffer.
Definition: imagediff.cpp:70
Scanline model interface.
Definition: scanlinemodel.h:55
~ImageDiff()
Destructor.
Definition: imagediff.cpp:59
bool different()
Check if images are different.
Definition: imagediff.cpp:102
unsigned int x
x coordinate
Definition: types.h:35
void setBufferB(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set second buffer.
Definition: imagediff.cpp:85