0024157: Parallelization of assembly part of BO
[occt.git] / src / Image / Image_Diff.hxx
1 // Created on: 2012-07-10
2 // Created by: VRO
3 // Copyright (c) 2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #ifndef _Image_Diff_H__
21 #define _Image_Diff_H__
22
23 #include <Image_PixMap.hxx>
24 #include <TCollection_AsciiString.hxx>
25 #include <TColStd_MapOfInteger.hxx>
26 #include <NCollection_List.hxx>
27 #include <NCollection_Vector.hxx>
28
29 //! This class compares two images pixel-by-pixel.
30 //! It uses the following methods to ignore the difference between images:
31 //!  - Black/White comparison. It makes the images 2-colored before the comparison.
32 //!  - Equality with tolerance. Colors of two pixels are considered the same if the
33 //!    differnce of their color is less than a tolerance.
34 //!  - Border filter. The algorithm ignores alone independent pixels,
35 //!    which are different on both images, ignores the "border effect" -
36 //!    the difference caused by triangles located at angle about 0 or 90 degrees to the user.
37 //!
38 //! Border filter ignores a difference in implementation of
39 //! anti-aliasing and other effects on boundary of a shape.
40 //! The triangles of a boundary zone are usually located so that their normals point aside the user
41 //! (about 90 degree between the normal and the direction to the user's eye).
42 //! Deflection of the light for such a triangle depends on implementation of the video driver.
43 //! In order to skip this difference the following algorithm is used:
44 //!  a) "Different" pixels are groupped and checked on "one-pixel width line".
45 //!     indeed, the pixels may represent not a line, but any curve.
46 //!     But the width of this curve should be not more than a pixel.
47 //!     This group of pixels become a candidate to be ignored because of boundary effect.
48 //!  b) The group of pixels is checked on belonging to a "shape".
49 //!     Neighbour pixels are checked from the reference image.
50 //!     This test confirms a fact that the group of pixels belongs to a shape and
51 //!     represent a boundary of the shape.
52 //!     In this case the whole group of pixels is ignored (considered as same).
53 //!     Otherwise, the group of pixels may represent a geometrical curve in the viewer 3D
54 //!     and should be considered as "different".
55 //!
56 //! References:
57 //!     1. http://pdiff.sourceforge.net/ypg01.pdf
58 //!     2. http://pdiff.sourceforge.net/metric.html
59 //!     3. http://www.cs.ucf.edu/~sumant/publications/sig99.pdf
60 //!     4. http://www.worldscientific.com/worldscibooks/10.1142/2641#t=toc (there is a list of articles and books in PDF format)
61
62 class Image_Diff : public Standard_Transient
63 {
64
65 public:
66
67   //! An empty constructor. Init() should be called for initialization.
68   Standard_EXPORT Image_Diff();
69
70   //! Desctructor.
71   Standard_EXPORT virtual ~Image_Diff();
72
73   //! Initialize algorithm by two images.
74   //! @return false if images has different or unsupported pixel format.
75   Standard_EXPORT Standard_Boolean Init (const Handle(Image_PixMap)& theImageRef,
76                                          const Handle(Image_PixMap)& theImageNew,
77                                          const Standard_Boolean      theToBlackWhite = Standard_False);
78
79   //! Initialize algorithm by two images (will be loaded from files).
80   //! @return false if images couldn't be opened or their format is unsupported.
81   Standard_EXPORT Standard_Boolean Init (const TCollection_AsciiString& theImgPathRef,
82                                          const TCollection_AsciiString& theImgPathNew,
83                                          const Standard_Boolean         theToBlackWhite = Standard_False);
84
85   //! Color tolerance for equality check. Should be within range 0..1:
86   //! Corresponds to a difference between white and black colors (maximum difference).
87   //! By default, the tolerance is equal to 0 thus equality check will return false for any different colors.
88   Standard_EXPORT void SetColorTolerance (const Standard_Real theTolerance);
89
90   //! Color tolerance for equality check.
91   Standard_EXPORT Standard_Real ColorTolerance() const;
92
93   //! Sets taking into account (ignoring) a "border effect" on comparison of images.
94   //! The border effect is caused by a border of shaded shapes in the viewer 3d.
95   //! Triangles of this area are located at about 0 or 90 degrees to the user.
96   //! Therefore, they deflect light differently according to implementation of a video card driver.
97   //! This flag allows to detect such a "border" area and skip it from comparison of images.
98   //! Filter turned OFF by default.
99   Standard_EXPORT void SetBorderFilterOn (const Standard_Boolean theToIgnore);
100
101   //! Returns a flag of taking into account (ignoring) a border effect in comparison of images.
102   Standard_EXPORT Standard_Boolean IsBorderFilterOn() const;
103
104   //! Compares two images. It returns a number of different pixels (or groups of pixels).
105   //! It returns -1 if algorithm not initialized before.
106   Standard_EXPORT Standard_Integer Compare();
107
108   //! Saves a difference between two images as white pixels on black backgroud.
109   Standard_EXPORT Standard_Boolean SaveDiffImage (Image_PixMap& theDiffImage) const;
110
111   //! Saves a difference between two images as white pixels on black backgroud.
112   Standard_EXPORT Standard_Boolean SaveDiffImage (const TCollection_AsciiString& theDiffPath) const;
113
114 protected:
115
116   //! Perform border filter algorithm.
117   Standard_EXPORT Standard_Integer ignoreBorderEffect();
118
119   //! Release dynamically allocated memory.
120   Standard_EXPORT void releaseGroupsOfDiffPixels();
121
122 protected:
123
124   typedef NCollection_List<TColStd_MapOfInteger* > ListOfMapOfInteger;
125
126   Handle(Image_PixMap)              myImageRef;           //!< reference image to compare (from)
127   Handle(Image_PixMap)              myImageNew;           //!< new       image to compare (to)
128   Standard_Real                     myColorTolerance;     //!< tolerance for equality check (0..1, 0 - any not equal, 1 - opposite colors)
129   Standard_Boolean                  myIsBorderFilterOn;   //!< perform algorithm with border effect filter
130   ListOfMapOfInteger                myGroupsOfDiffPixels;
131   NCollection_Vector<Standard_Size> myDiffPixels;         //!< different pixels (position packed into integer)
132   TColStd_MapOfInteger              myLinearGroups;
133
134 public:
135
136   DEFINE_STANDARD_RTTI(Image_Diff) // Type definition
137
138 };
139
140 DEFINE_STANDARD_HANDLE(Image_Diff, Standard_Transient)
141
142 #endif // _Image_Diff_H__