6aca4d39 |
1 | // Created on: 2012-07-10 |
692613e5 |
2 | // Created by: VRO |
6aca4d39 |
3 | // Copyright (c) 2012-2014 OPEN CASCADE SAS |
692613e5 |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
692613e5 |
6 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
692613e5 |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
692613e5 |
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_MapOfInteger.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 | //! differnce 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". |
185e6ec0 |
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 | |
692613e5 |
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 | //! Desctructor. |
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 | Standard_EXPORT void SetColorTolerance (const Standard_Real theTolerance); |
85 | |
86 | //! Color tolerance for equality check. |
87 | Standard_EXPORT Standard_Real ColorTolerance() const; |
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 | Standard_EXPORT void SetBorderFilterOn (const Standard_Boolean theToIgnore); |
96 | |
97 | //! Returns a flag of taking into account (ignoring) a border effect in comparison of images. |
98 | Standard_EXPORT Standard_Boolean IsBorderFilterOn() const; |
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 backgroud. |
105 | Standard_EXPORT Standard_Boolean SaveDiffImage (Image_PixMap& theDiffImage) const; |
106 | |
107 | //! Saves a difference between two images as white pixels on black backgroud. |
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 | typedef NCollection_List<TColStd_MapOfInteger* > ListOfMapOfInteger; |
121 | |
122 | Handle(Image_PixMap) myImageRef; //!< reference image to compare (from) |
123 | Handle(Image_PixMap) myImageNew; //!< new image to compare (to) |
124 | Standard_Real myColorTolerance; //!< tolerance for equality check (0..1, 0 - any not equal, 1 - opposite colors) |
125 | Standard_Boolean myIsBorderFilterOn; //!< perform algorithm with border effect filter |
126 | ListOfMapOfInteger myGroupsOfDiffPixels; |
127 | NCollection_Vector<Standard_Size> myDiffPixels; //!< different pixels (position packed into integer) |
128 | TColStd_MapOfInteger myLinearGroups; |
129 | |
130 | public: |
131 | |
92efcf78 |
132 | DEFINE_STANDARD_RTTIEXT(Image_Diff,Standard_Transient) // Type definition |
692613e5 |
133 | |
134 | }; |
135 | |
136 | DEFINE_STANDARD_HANDLE(Image_Diff, Standard_Transient) |
137 | |
138 | #endif // _Image_Diff_H__ |