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/color/yuv.h>
25 #include <fvutils/statistical/imagediff.h>
26 
27 #include <cstdlib>
28 
29 namespace firevision {
30 
31 /** @class ImageDiff <fvutils/statistical/imagediff.h>
32  * Image difference checker.
33  * @author Tim Niemueller
34  */
35 
36 /** Constructor.
37  * @param scanline_model scanlinemodel to use, if null all pixels
38  * are compared.
39  */
40 ImageDiff::ImageDiff(ScanlineModel *scanline_model)
41 {
42  this->scanline_model = scanline_model;
43 }
44 
45 /** Constructor.
46  * Use this constructor to compare all pixels.
47  */
49 {
50  scanline_model = NULL;
51 }
52 
53 /** Destructor. */
55 {
56 }
57 
58 /** Set first buffer.
59  * @param yuv422planar_buffer buffer
60  * @param width image width in pixels
61  * @param height image height in pixels
62  */
63 void
64 ImageDiff::setBufferA(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
65 {
66  buffer_a = yuv422planar_buffer;
67  width_a = width;
68  height_a = height;
69 }
70 
71 /** Set second buffer.
72  * @param yuv422planar_buffer buffer
73  * @param width image width in pixels
74  * @param height image height in pixels
75  */
76 void
77 ImageDiff::setBufferB(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
78 {
79  buffer_b = yuv422planar_buffer;
80  width_b = width;
81  height_b = height;
82 }
83 
84 /** Check if images are different.
85  * This method will compare the two images. If any pixel marked by
86  * the scanline or any pixel at all if no scanline model is given
87  * differ the images are considered to be different. The same applies
88  * if any buffer is unset or the widths or heights are not the same.
89  * @return true if images are different, false otherwise
90  */
91 bool
93 {
94  if ((buffer_a == NULL) && (buffer_b == NULL))
95  return false;
96  if ((buffer_a == NULL) && (buffer_b != NULL))
97  return true;
98  if ((buffer_a != NULL) && (buffer_b == NULL))
99  return true;
100  if ((width_a != width_b) || (height_a != height_b))
101  return true;
102 
103  if (scanline_model != NULL) {
104  // use the supplied scanline model
105 
106  unsigned int x, y;
107  unsigned char y_a, u_a, v_a, y_b, u_b, v_b;
108 
109  scanline_model->reset();
110  while (!scanline_model->finished()) {
111  x = (*scanline_model)->x;
112  y = (*scanline_model)->y;
113 
114  YUV422_PLANAR_YUV(buffer_a, width_a, height_a, x, y, y_a, u_a, v_a);
115  YUV422_PLANAR_YUV(buffer_b, width_b, height_b, x, y, y_b, u_b, v_b);
116 
117  if ((y_a != y_b) || (u_a != u_b) || (v_a != v_b)) {
118  return true;
119  }
120  }
121  } else {
122  // no scanline model, check every single pixel
123 
124  unsigned char *ypa = buffer_a;
125  unsigned char *ypb = buffer_b;
126 
127  for (unsigned int i = 0; i < (width_a * height_a); ++i) {
128  if (*ypa != *ypb) {
129  return true;
130  }
131  ++ypa;
132  ++ypb;
133  }
134  }
135 
136  return false;
137 }
138 
139 /** Number of differing pixels.
140  * Executes the same routine as different(). But instead of just saying that
141  * the images are different will tell how many pixels differ.
142  * @return number of different pixels
143  */
144 unsigned int
146 {
147  if ((buffer_a == NULL) && (buffer_b == NULL))
148  return 0;
149  if ((buffer_a == NULL) && (buffer_b != NULL))
150  return (width_b * height_b);
151  if ((buffer_a != NULL) && (buffer_b == NULL))
152  return (width_a * height_a);
153  if ((width_a != width_b) || (height_a != height_b)) {
154  return std::abs((long)width_a - (long)width_b) * std::abs((long)height_a - (long)height_b);
155  }
156 
157  unsigned int num = 0;
158  if (scanline_model != NULL) {
159  // use the supplied scanline model
160 
161  unsigned int x, y;
162  unsigned char y_a, u_a, v_a, y_b, u_b, v_b;
163 
164  scanline_model->reset();
165  while (!scanline_model->finished()) {
166  x = (*scanline_model)->x;
167  y = (*scanline_model)->y;
168 
169  YUV422_PLANAR_YUV(buffer_a, width_a, height_a, x, y, y_a, u_a, v_a);
170  YUV422_PLANAR_YUV(buffer_b, width_b, height_b, x, y, y_b, u_b, v_b);
171 
172  if ((y_a != y_b) || (u_a != u_b) || (v_a != v_b)) {
173  ++num;
174  }
175  }
176  } else {
177  // no scanline model, check every single pixel
178 
179  unsigned char *ypa = buffer_a;
180  unsigned char *ypb = buffer_b;
181 
182  for (unsigned int i = 0; i < (width_a * height_a); ++i) {
183  if (*ypa++ != *ypb++)
184  ++num;
185  }
186  }
187  return num;
188 }
189 
190 } // end namespace firevision
firevision::ImageDiff::setBufferB
void setBufferB(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set second buffer.
Definition: imagediff.cpp:83
firevision::ImageDiff::numDifferingPixels
unsigned int numDifferingPixels()
Number of differing pixels.
Definition: imagediff.cpp:151
firevision::ImageDiff::ImageDiff
ImageDiff()
Constructor.
Definition: imagediff.cpp:54
firevision::ImageDiff::setBufferA
void setBufferA(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set first buffer.
Definition: imagediff.cpp:70
firevision::ImageDiff::~ImageDiff
~ImageDiff()
Destructor.
Definition: imagediff.cpp:60
firevision::ImageDiff::different
bool different()
Check if images are different.
Definition: imagediff.cpp:98
fawkes::upoint_t::x
unsigned int x
x coordinate
Definition: types.h:36