1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
19 /** \file
20  * \ingroup freestyle
21  * \brief Convenient access to the steerable ViewMap to which any element of the ViewMap belongs
22  * to.
23  */
24 
25 #include <map>
26 
27 #include "../geometry/Geom.h"
28 
29 #include "../system/FreestyleConfig.h"
30 
31 #ifdef WITH_CXX_GUARDEDALLOC
32 #  include "MEM_guardedalloc.h"
33 #endif
34 
35 using namespace std;
36 
37 namespace Freestyle {
38 
39 using namespace Geometry;
40 
41 class FEdge;
42 class ImagePyramid;
43 class GrayImage;
44 
45 /*! This class checks for every FEdge in which steerable it belongs and stores the mapping
46  *  allowing to retrieve this information from the FEdge Id.
47  */
48 class SteerableViewMap {
49  protected:
50   // for each vector the list of nbOrientations weights corresponding to its contributions
51   // to the nbOrientations directional maps
52   map<unsigned int, double *> _mapping;
53   unsigned _nbOrientations;
54   ImagePyramid **_imagesPyramids;  // the pyramids of images storing the different SVM
55 
56   // internal
57   double _bound;  // cos(Pi/N)
58   vector<Vec2d> _directions;
59 
60  public:
61   SteerableViewMap(unsigned int nbOrientations = 4);
62   SteerableViewMap(const SteerableViewMap &iBrother);
63   virtual ~SteerableViewMap();
64 
65   /*! Resets everything */
66   virtual void Reset();
67 
68   /*! Adds a FEdge to steerable VM.
69    *  Returns the nbOrientations weights corresponding to the FEdge contributions to the
70    *  nbOrientations directional maps.
71    */
72   double *AddFEdge(FEdge *iFEdge);
73 
74   /*! Compute the weight of direction dir for orientation iNOrientation */
75   double ComputeWeight(const Vec2d &dir, unsigned iNOrientation);
76 
77   /*! Returns the number of the SVM to which a direction belongs to.
78    *  \param dir:
79    *    The direction
80    */
81   unsigned getSVMNumber(Vec2f dir);
82 
83   /*! Returns the number of the SVM to which a FEdge belongs most.
84    *  \param id:
85    *    The First element of the Id struct of the FEdge we're interested in.
86    */
87   unsigned getSVMNumber(unsigned id);
88 
89   /*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images of the
90    *  steerable viewmap.
91    *  \param steerableBases:
92    *    The _nbOrientations+1 images constituting the basis for the steerable pyramid.
93    *  \param copy:
94    *    If false, the data is not duplicated, and Canvas deals with the memory management of these
95    *    _nbOrientations+1 images. If true, data is copied, and it's up to the caller to delete
96    *    the images.
97    *  \param iNbLevels:
98    *    The number of levels desired for each pyramid.
99    *    If iNbLevels == 0, the complete pyramid is built.
100    *  \param iSigma:
101    *    The sigma that will be used for the gaussian blur
102    */
103   void buildImagesPyramids(GrayImage **steerableBases,
104                            bool copy = false,
105                            unsigned iNbLevels = 4,
106                            float iSigma = 1.0f);
107 
108   /*! Reads a pixel value in one of the VewMap density steerable pyramids.
109    *  Returns a value between 0 and 1.
110    *  \param iOrientation:
111    *    the number telling which orientation we need to check.
112    *    There are _nbOrientations+1 oriented ViewMaps:
113    *    0 -> the ViewMap containing every horizontal lines
114    *    1 -> the ViewMap containing every lines whose orientation is around PI/4
115    *    2 -> the ViewMap containing every vertical lines
116    *    3 -> the ViewMap containing every lines whose orientation is around 3PI/4
117    *    4 -> the complete ViewMap
118    *  \param iLevel:
119    *    The level of the pyramid we want to read
120    *  \param x:
121    *    The abscissa of the desired pixel specified in level0 coordinate system.
122    *    The origin is the lower left corner.
123    *  \param y:
124    *    The ordinate of the desired pixel specified in level0 coordinate system.
125    *    The origin is the lower left corner.
126    */
127   float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y);
128 
129   /*! Reads a pixel in the one of the level of the pyramid containing the images
130    *  of the complete ViewMap.
131    *  Returns a value between 0 and 1.
132    *  Equivalent to : readSteerableViewMapPixel(nbOrientations, x, y)
133    */
134   float readCompleteViewMapPixel(int iLevel, int x, int y);
135 
136   /*! Returns the number of levels in the pyramids */
137   unsigned int getNumberOfPyramidLevels() const;
138 
139   /*! Returns the number of orientations */
getNumberOfOrientations()140   unsigned int getNumberOfOrientations() const
141   {
142     return _nbOrientations;
143   }
144 
145   /*! for debug purposes */
146   void saveSteerableViewMap() const;
147 
148  protected:
149   void Clear();
150   void Build();
151 
152 #ifdef WITH_CXX_GUARDEDALLOC
153   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SteerableViewMap")
154 #endif
155 };
156 
157 } /* namespace Freestyle */
158