0031939: Coding - correction of spelling errors in comments [part 4]
[occt.git] / src / Image / Image_Diff.hxx
1 // Created on: 2012-07-10
2 // Created by: VRO
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _Image_Diff_H__
17 #define _Image_Diff_H__
18
19 #include <Image_PixMap.hxx>
20 #include <TCollection_AsciiString.hxx>
21 #include <TColStd_HPackedMapOfInteger.hxx>
22 #include <NCollection_List.hxx>
23 #include <NCollection_Vector.hxx>
24
25 //! This class compares two images pixel-by-pixel.
26 //! It uses the following methods to ignore the difference between images:
27 //!  - Black/White comparison. It makes the images 2-colored before the comparison.
28 //!  - Equality with tolerance. Colors of two pixels are considered the same if the
29 //!    difference of their color is less than a tolerance.
30 //!  - Border filter. The algorithm ignores alone independent pixels,
31 //!    which are different on both images, ignores the "border effect" -
32 //!    the difference caused by triangles located at angle about 0 or 90 degrees to the user.
33 //!
34 //! Border filter ignores a difference in implementation of
35 //! anti-aliasing and other effects on boundary of a shape.
36 //! The triangles of a boundary zone are usually located so that their normals point aside the user
37 //! (about 90 degree between the normal and the direction to the user's eye).
38 //! Deflection of the light for such a triangle depends on implementation of the video driver.
39 //! In order to skip this difference the following algorithm is used:
40 //!  a) "Different" pixels are groupped and checked on "one-pixel width line".
41 //!     indeed, the pixels may represent not a line, but any curve.
42 //!     But the width of this curve should be not more than a pixel.
43 //!     This group of pixels become a candidate to be ignored because of boundary effect.
44 //!  b) The group of pixels is checked on belonging to a "shape".
45 //!     Neighbour pixels are checked from the reference image.
46 //!     This test confirms a fact that the group of pixels belongs to a shape and
47 //!     represent a boundary of the shape.
48 //!     In this case the whole group of pixels is ignored (considered as same).
49 //!     Otherwise, the group of pixels may represent a geometrical curve in the viewer 3D
50 //!     and should be considered as "different".
51 //!
52 //! References:
53 //!     1. http://pdiff.sourceforge.net/ypg01.pdf
54 //!     2. http://pdiff.sourceforge.net/metric.html
55 //!     3. http://www.cs.ucf.edu/~sumant/publications/sig99.pdf
56 //!     4. http://www.worldscientific.com/worldscibooks/10.1142/2641#t=toc (there is a list of articles and books in PDF format)
57
58 class Image_Diff : public Standard_Transient
59 {
60
61 public:
62
63   //! An empty constructor. Init() should be called for initialization.
64   Standard_EXPORT Image_Diff();
65
66   //! Destructor.
67   Standard_EXPORT virtual ~Image_Diff();
68
69   //! Initialize algorithm by two images.
70   //! @return false if images has different or unsupported pixel format.
71   Standard_EXPORT Standard_Boolean Init (const Handle(Image_PixMap)& theImageRef,
72                                          const Handle(Image_PixMap)& theImageNew,
73                                          const Standard_Boolean      theToBlackWhite = Standard_False);
74
75   //! Initialize algorithm by two images (will be loaded from files).
76   //! @return false if images couldn't be opened or their format is unsupported.
77   Standard_EXPORT Standard_Boolean Init (const TCollection_AsciiString& theImgPathRef,
78                                          const TCollection_AsciiString& theImgPathNew,
79                                          const Standard_Boolean         theToBlackWhite = Standard_False);
80
81   //! Color tolerance for equality check. Should be within range 0..1:
82   //! Corresponds to a difference between white and black colors (maximum difference).
83   //! By default, the tolerance is equal to 0 thus equality check will return false for any different colors.
84   void SetColorTolerance (const Standard_Real theTolerance) {  myColorTolerance = theTolerance; }
85
86   //! Color tolerance for equality check.
87   Standard_Real ColorTolerance() const { return myColorTolerance; }
88
89   //! Sets taking into account (ignoring) a "border effect" on comparison of images.
90   //! The border effect is caused by a border of shaded shapes in the viewer 3d.
91   //! Triangles of this area are located at about 0 or 90 degrees to the user.
92   //! Therefore, they deflect light differently according to implementation of a video card driver.
93   //! This flag allows to detect such a "border" area and skip it from comparison of images.
94   //! Filter turned OFF by default.
95   void SetBorderFilterOn (const Standard_Boolean theToIgnore) { myIsBorderFilterOn = theToIgnore; }
96
97   //! Returns a flag of taking into account (ignoring) a border effect in comparison of images.
98   Standard_Boolean IsBorderFilterOn() const { return myIsBorderFilterOn; }
99
100   //! Compares two images. It returns a number of different pixels (or groups of pixels).
101   //! It returns -1 if algorithm not initialized before.
102   Standard_EXPORT Standard_Integer Compare();
103
104   //! Saves a difference between two images as white pixels on black background.
105   Standard_EXPORT Standard_Boolean SaveDiffImage (Image_PixMap& theDiffImage) const;
106
107   //! Saves a difference between two images as white pixels on black background.
108   Standard_EXPORT Standard_Boolean SaveDiffImage (const TCollection_AsciiString& theDiffPath) const;
109
110 protected:
111
112   //! Perform border filter algorithm.
113   Standard_EXPORT Standard_Integer ignoreBorderEffect();
114
115   //! Release dynamically allocated memory.
116   Standard_EXPORT void releaseGroupsOfDiffPixels();
117
118 protected:
119
120   //! Map two pixel coordinates to 32-bit integer
121   static Standard_Integer PackXY (uint16_t theX, uint16_t theY)
122   {
123     return Standard_Integer((unsigned int)theY | 
124                            ((unsigned int)theX << 16));
125   }
126
127   //! Get pixel X coordinate from 32-bit packed integer
128   static uint16_t UnpackX (Standard_Integer theXY)
129   {
130     return (uint16_t)(((unsigned int)theXY & 0xffff0000) >> 16);
131   }
132
133   //! Get pixel Y coordinate from 32-bit packed integer
134   static uint16_t UnpackY (Standard_Integer theXY)
135   {
136     return (uint16_t)((unsigned int)theXY & 0xffff);
137   }
138
139 protected:
140
141   Handle(Image_PixMap)              myImageRef;           //!< reference image to compare (from)
142   Handle(Image_PixMap)              myImageNew;           //!< new       image to compare (to)
143   Standard_Real                     myColorTolerance;     //!< tolerance for equality check (0..1, 0 - any not equal, 1 - opposite colors)
144
145   Standard_Boolean                  myIsBorderFilterOn;   //!< perform algorithm with border effect filter
146
147   //! coordinates of different pixels, packed in one int using 16-bit integers to save memory
148   NCollection_Vector<Standard_Integer> myDiffPixels;
149   TColStd_PackedMapOfInteger        myLinearGroups;
150   NCollection_List<Handle(TColStd_HPackedMapOfInteger)>
151                                     myGroupsOfDiffPixels;
152
153 public:
154
155   DEFINE_STANDARD_RTTIEXT(Image_Diff,Standard_Transient) // Type definition
156
157 };
158
159 DEFINE_STANDARD_HANDLE(Image_Diff, Standard_Transient)
160
161 #endif // _Image_Diff_H__