|
|
|||
File indexing completed on 2026-06-13 08:30:33
0001 // Created on: 2012-07-10 0002 // Created by: VRO 0003 // Copyright (c) 2012-2014 OPEN CASCADE SAS 0004 // 0005 // This file is part of Open CASCADE Technology software library. 0006 // 0007 // This library is free software; you can redistribute it and/or modify it under 0008 // the terms of the GNU Lesser General Public License version 2.1 as published 0009 // by the Free Software Foundation, with special exception defined in the file 0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 0011 // distribution for complete text of the license and disclaimer of any warranty. 0012 // 0013 // Alternatively, this file may be used under the terms of Open CASCADE 0014 // commercial license or contractual agreement. 0015 0016 #ifndef Image_Diff_HeaderFile 0017 #define Image_Diff_HeaderFile 0018 0019 #include <Image_PixMap.hxx> 0020 #include <TCollection_AsciiString.hxx> 0021 #include <TColStd_HPackedMapOfInteger.hxx> 0022 #include <NCollection_List.hxx> 0023 #include <NCollection_Vector.hxx> 0024 0025 //! This class compares two images pixel-by-pixel. 0026 //! It uses the following methods to ignore the difference between images: 0027 //! - Black/White comparison. It makes the images 2-colored before the comparison. 0028 //! - Equality with tolerance. Colors of two pixels are considered the same if the 0029 //! difference of their color is less than a tolerance. 0030 //! - Border filter. The algorithm ignores alone independent pixels, 0031 //! which are different on both images, ignores the "border effect" - 0032 //! the difference caused by triangles located at angle about 0 or 90 degrees to the user. 0033 //! 0034 //! Border filter ignores a difference in implementation of 0035 //! anti-aliasing and other effects on boundary of a shape. 0036 //! The triangles of a boundary zone are usually located so that their normals point aside the user 0037 //! (about 90 degree between the normal and the direction to the user's eye). 0038 //! Deflection of the light for such a triangle depends on implementation of the video driver. 0039 //! In order to skip this difference the following algorithm is used: 0040 //! a) "Different" pixels are grouped and checked on "one-pixel width line". 0041 //! indeed, the pixels may represent not a line, but any curve. 0042 //! But the width of this curve should be not more than a pixel. 0043 //! This group of pixels become a candidate to be ignored because of boundary effect. 0044 //! b) The group of pixels is checked on belonging to a "shape". 0045 //! Neighbour pixels are checked from the reference image. 0046 //! This test confirms a fact that the group of pixels belongs to a shape and 0047 //! represent a boundary of the shape. 0048 //! In this case the whole group of pixels is ignored (considered as same). 0049 //! Otherwise, the group of pixels may represent a geometrical curve in the viewer 3D 0050 //! and should be considered as "different". 0051 //! 0052 //! References: 0053 //! 1. http://pdiff.sourceforge.net/ypg01.pdf 0054 //! 2. http://pdiff.sourceforge.net/metric.html 0055 //! 3. http://www.cs.ucf.edu/~sumant/publications/sig99.pdf 0056 //! 4. http://www.worldscientific.com/worldscibooks/10.1142/2641#t=toc (there is a list of 0057 //! articles and books in PDF format) 0058 0059 class Image_Diff : public Standard_Transient 0060 { 0061 0062 public: 0063 //! An empty constructor. Init() should be called for initialization. 0064 Standard_EXPORT Image_Diff(); 0065 0066 //! Destructor. 0067 Standard_EXPORT virtual ~Image_Diff(); 0068 0069 //! Initialize algorithm by two images. 0070 //! @return false if images has different or unsupported pixel format. 0071 Standard_EXPORT Standard_Boolean Init(const Handle(Image_PixMap)& theImageRef, 0072 const Handle(Image_PixMap)& theImageNew, 0073 const Standard_Boolean theToBlackWhite = Standard_False); 0074 0075 //! Initialize algorithm by two images (will be loaded from files). 0076 //! @return false if images couldn't be opened or their format is unsupported. 0077 Standard_EXPORT Standard_Boolean Init(const TCollection_AsciiString& theImgPathRef, 0078 const TCollection_AsciiString& theImgPathNew, 0079 const Standard_Boolean theToBlackWhite = Standard_False); 0080 0081 //! Color tolerance for equality check. Should be within range 0..1: 0082 //! Corresponds to a difference between white and black colors (maximum difference). 0083 //! By default, the tolerance is equal to 0 thus equality check will return false for any 0084 //! different colors. 0085 void SetColorTolerance(const Standard_Real theTolerance) { myColorTolerance = theTolerance; } 0086 0087 //! Color tolerance for equality check. 0088 Standard_Real ColorTolerance() const { return myColorTolerance; } 0089 0090 //! Sets taking into account (ignoring) a "border effect" on comparison of images. 0091 //! The border effect is caused by a border of shaded shapes in the viewer 3d. 0092 //! Triangles of this area are located at about 0 or 90 degrees to the user. 0093 //! Therefore, they deflect light differently according to implementation of a video card driver. 0094 //! This flag allows to detect such a "border" area and skip it from comparison of images. 0095 //! Filter turned OFF by default. 0096 void SetBorderFilterOn(const Standard_Boolean theToIgnore) { myIsBorderFilterOn = theToIgnore; } 0097 0098 //! Returns a flag of taking into account (ignoring) a border effect in comparison of images. 0099 Standard_Boolean IsBorderFilterOn() const { return myIsBorderFilterOn; } 0100 0101 //! Compares two images. It returns a number of different pixels (or groups of pixels). 0102 //! It returns -1 if algorithm not initialized before. 0103 Standard_EXPORT Standard_Integer Compare(); 0104 0105 //! Saves a difference between two images as white pixels on black background. 0106 Standard_EXPORT Standard_Boolean SaveDiffImage(Image_PixMap& theDiffImage) const; 0107 0108 //! Saves a difference between two images as white pixels on black background. 0109 Standard_EXPORT Standard_Boolean SaveDiffImage(const TCollection_AsciiString& theDiffPath) const; 0110 0111 protected: 0112 //! Perform border filter algorithm. 0113 Standard_EXPORT Standard_Integer ignoreBorderEffect(); 0114 0115 //! Release dynamically allocated memory. 0116 Standard_EXPORT void releaseGroupsOfDiffPixels(); 0117 0118 protected: 0119 //! Map two pixel coordinates to 32-bit integer 0120 static Standard_Integer PackXY(uint16_t theX, uint16_t theY) 0121 { 0122 return Standard_Integer((unsigned int)theY | ((unsigned int)theX << 16)); 0123 } 0124 0125 //! Get pixel X coordinate from 32-bit packed integer 0126 static uint16_t UnpackX(Standard_Integer theXY) 0127 { 0128 return (uint16_t)(((unsigned int)theXY & 0xffff0000) >> 16); 0129 } 0130 0131 //! Get pixel Y coordinate from 32-bit packed integer 0132 static uint16_t UnpackY(Standard_Integer theXY) 0133 { 0134 return (uint16_t)((unsigned int)theXY & 0xffff); 0135 } 0136 0137 protected: 0138 Handle(Image_PixMap) myImageRef; //!< reference image to compare (from) 0139 Handle(Image_PixMap) myImageNew; //!< new image to compare (to) 0140 // clang-format off 0141 Standard_Real myColorTolerance; //!< tolerance for equality check (0..1, 0 - any not equal, 1 - opposite colors) 0142 0143 Standard_Boolean myIsBorderFilterOn; //!< perform algorithm with border effect filter 0144 // clang-format on 0145 0146 //! coordinates of different pixels, packed in one int using 16-bit integers to save memory 0147 NCollection_Vector<Standard_Integer> myDiffPixels; 0148 TColStd_PackedMapOfInteger myLinearGroups; 0149 NCollection_List<Handle(TColStd_HPackedMapOfInteger)> myGroupsOfDiffPixels; 0150 0151 public: 0152 DEFINE_STANDARD_RTTIEXT(Image_Diff, Standard_Transient) // Type definition 0153 }; 0154 0155 DEFINE_STANDARD_HANDLE(Image_Diff, Standard_Transient) 0156 0157 #endif // _Image_Diff_H__
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|