Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleImageDiff.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 /**
27  * @example ExampleImageDiff.cpp
28  @relates Image
29  @brief Example for difference calculation of images:
30  Takes two RGB input images and calculates the difference between them.
31  Should be used for images that were taken from the same viewpoint with
32  different aperture/exposure to visualize the difference in the two
33  images.
34  If the images are bigger than 1024x256 the difference for each channel
35  will be visualized in a diagram as well.
36 
37  NOTE THAT the first image should be the brighter one! If you don't stick
38  to this, the diff image might be black due to (prevented) underflows!
39 
40  @ingroup g_examples
41  @author rwulff
42 */
43 
44 #include <Base/Image/Image.hh>
45 #include <Base/Image/ImageIO.hh>
46 #include <Base/ImageUtils/ImageDraw.hh>
47 
48 
49 using namespace BIAS;
50 using namespace std;
51 
52 int main(int argc, char *argv[]) {
53 
54  // check params
55  if (argc < 3) {
56  cout << "wrong parameter count!!" << endl << endl;
57  cout << "usage:" << endl;
58  cout << argv[0] << " " << "<brighter_image> <darker_image>" << endl;
59  return -1;
60  }
61 
62  // load images (suppose that first image is the brighter one)
65  if (ImageIO::Load(argv[1], im1) != 0) {
66  cout << "image 1 could not be loaded!" << endl;
67  return -1;
68  }
69  else {
70  cout << "image 1 loaded!" << endl;
71  }
72  if (ImageIO::Load(argv[2], im2) != 0) {
73  cout << "image 2 could not be loaded!" << endl;
74  return -1;
75  }
76  else {
77  cout << "image 2 loaded!" << endl;
78  }
79 
80  cout << "images loaded" << endl;
81 
82  // ensure that input images have same size and RGB color model and init diffImage
83  BIASASSERT(im1.GetWidth() == im2.GetWidth() && im1.GetHeight() == im2.GetHeight());
84  BIASASSERT(im1.GetColorModel() == ImageBase::CM_RGB && im2.GetColorModel() == ImageBase::CM_RGB);
85  Image<unsigned char> imDiff(im1);
86 
87  // draw per-channel differences only if pictures are at least 1024x256
88  bool drawChannelDiffs = im1.GetWidth() >= 1024 && im1.GetHeight() >= 256;
89 
90  // get image data
91  unsigned char *im1Data = im1.GetImageData();
92  unsigned char *im2Data = im2.GetImageData();
93  unsigned char *imDiffData = imDiff.GetImageData();
94  unsigned int offset = 0;
95  int diff = 0;
96  unsigned int gammaX, gammaY;
97 
98  cout << "starting iteration..." << endl;
99 
100  // iterate over pixels and draw difference image
101  for (unsigned int y = 0; y < im1.GetHeight(); y++) {
102  for (unsigned int x = 0; x < im1.GetWidth(); x++) {
103  offset = y*im1.GetWidth()*im1.GetChannelCount() + x*im1.GetChannelCount();
104 
105  // produce difference image in gray-scale
106  diff = (int)im1Data[offset] - (int)im2Data[offset]
107  + (int)im1Data[offset+1] - (int)im2Data[offset+1]
108  + (int)im1Data[offset+2] - (int)im2Data[offset+2];
109  diff /= 3;
110 
111  diff = diff < 0 ? 0 : diff;
112  diff = diff > 255 ? 255 : diff;
113  imDiffData[offset] = (unsigned char)diff;
114  imDiffData[offset+1] = (unsigned char)diff;
115  imDiffData[offset+2] = (unsigned char)diff;
116 
117  // draw per-channel difference visualiziation
118  if (drawChannelDiffs) {
119  // red
120  gammaX = (unsigned int)im1Data[offset];
121  gammaY = 256 - (unsigned int)im2Data[offset];
122  imDiffData[gammaY*im1.GetWidth()*im1.GetChannelCount() + gammaX*im1.GetChannelCount()]
123  = 255;
124 
125  // green
126  gammaX = (unsigned int)im1Data[offset+1] + 256;
127  gammaY = 256 - (unsigned int)im2Data[offset+1];
128  imDiffData[gammaY*im1.GetWidth()*im1.GetChannelCount() + gammaX*im1.GetChannelCount() + 1]
129  = 255;
130 
131  // blue
132  gammaX = (unsigned int)im1Data[offset+2] + 512;
133  gammaY = 256 - (unsigned int)im2Data[offset+2];
134  imDiffData[gammaY*im1.GetWidth()*im1.GetChannelCount() + gammaX*im1.GetChannelCount() + 2]
135  = 255;
136 
137  // arithmetic mean
138  gammaX = (unsigned int)im1Data[offset] + (unsigned int)im1Data[offset+1] + (unsigned int)im1Data[offset+2];
139  gammaX /= 3;
140  gammaX += 768;
141  gammaY = (unsigned int)im2Data[offset] + (unsigned int)im2Data[offset+1] + (unsigned int)im2Data[offset+2];
142  gammaY /= 3;
143  gammaY = 256 - gammaY;
144  offset = gammaY*im1.GetWidth()*im1.GetChannelCount() + gammaX*im1.GetChannelCount();
145  imDiffData[offset] = 255;
146  imDiffData[offset + 1] = 255;
147  imDiffData[offset + 2] = 255;
148  }
149  }
150  }
151 
152  ImageIO::Save("diff.mip", imDiff);
153 
154  cout << "done!" << endl;
155 
156  return 0;
157 }
unsigned int GetWidth() const
Definition: ImageBase.hh:312
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
unsigned int GetHeight() const
Definition: ImageBase.hh:319
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
static int Load(const std::string &FileName, ImageBase &img)
first tries a call to Read MIP image and if that fails, tries to Import Image with all other availabl...
Definition: ImageIO.cpp:141