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
29namespace 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 */
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 */
63void
64ImageDiff::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 */
76void
77ImageDiff::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 */
91bool
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 */
144unsigned 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
void setBufferA(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set first buffer.
Definition: imagediff.cpp:64
unsigned int numDifferingPixels()
Number of differing pixels.
Definition: imagediff.cpp:145
void setBufferB(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set second buffer.
Definition: imagediff.cpp:77
ImageDiff()
Constructor.
Definition: imagediff.cpp:48
bool different()
Check if images are different.
Definition: imagediff.cpp:92
~ImageDiff()
Destructor.
Definition: imagediff.cpp:54
Scanline model interface.
Definition: scanlinemodel.h:53
unsigned int x
x coordinate
Definition: types.h:36