1 // This is gel/vdgl/vdgl_digital_region.h
2 #ifndef vdgl_digital_region_h_
3 #define vdgl_digital_region_h_
4 //:
5 // \file
6 // \brief A representation of the digital interior of a region.
7 //
8 //  Maintains the discrete geometry and intensity data of a Face, a 2-d
9 //  analog of EdgelChain. So far the class is a very simple group of 1-d
10 //  arrays for holding the x and y pixel locations and the intensity.
11 //  The class maintains 2d pixels in the style of TargetJr and could be
12 //  used to represent 2-d intensity points. To create a region with
13 //  a given number of pixel data , SetNpts(n); for(i = 0; i<n; ++i){
14 //                                         IncrementMeans(X[i],Y[i],I[i]);
15 //                                         InsertInPixelArrays(X[i],Y[i],I[i]);}
16 // \author
17 //   Joe Mundy November 27, 1999
18 //   GE Corporate Research and Development.
19 //
20 // \verbatim
21 // Modifications
22 //   8-May-2002 - Peter Vanroose - now inherits from vsol_region_2d
23 //  15-May-2002 - Peter Vanroose - inconsistency Xi() versus Ix() removed
24 //                (There were three pairs of data members both referring to
25 //                 intensity information, but only one of them was updated.)
26 //   8-Jan-2003 - Peter Vanroose - added is_convex() (virtual of vsol_region_2d)
27 //  22-Sep-2004 - Peter Vanroose - removed 3D interface: class is intrinsically 2D
28 //  22-Sep-2004 - Peter Vanroose - added transform() (projective transformation)
29 //  22-Sep-2004 - Peter Vanroose - added histogram() and residual_histogram()
30 // \endverbatim
31 //-----------------------------------------------------------------------------
32 
33 #include <vector>
34 #include <iostream>
35 #include <string>
36 #ifdef _MSC_VER
37 #  include <vcl_msvc_warnings.h>
38 #endif
39 #include <vnl/vnl_double_3x3.h>
40 #include <vnl/vnl_float_3x3.h>
41 #include <vnl/vnl_float_2.h>
42 #include <vsol/vsol_region_2d.h>
43 #include <vsol/vsol_point_2d.h>
44 class vdgl_digital_region : public vsol_region_2d
45 {
46  public:
47 
48   // Constructors/Initializers/Destructors---------------------------------
vdgl_digital_region()49    vdgl_digital_region() : vsol_region_2d(), min_((unsigned short)(-1)) {}
50 
51    vdgl_digital_region(int npts, const float *xp, const float *yp,
52                        const unsigned short *pix);
53    vdgl_digital_region(vdgl_digital_region const &r);
54    ~vdgl_digital_region() override;
55 
56    // Data Access-----------------------------------------------------------
57    // Data storage for the pixel arrays
58    void ResetPixelData();
59    void IncrementMeans(float x, float y, unsigned short pix);
60    void InitPixelArrays();
61    void SetNpts(int npts);
62    void InsertInPixelArrays(float x, float y, unsigned short pix);
63 
64    //: The region pixel coordinates and intensities
Xj()65    float const *Xj() const { return xp_; }
Yj()66    float const *Yj() const { return yp_; }
Ij()67    unsigned short const *Ij() const { return pix_; }
Npix()68    unsigned int Npix() const { return npts_; }
69 
70    //: The size of a region pixel in image pixel units
71    //(due to expanded resolution processing)
set_pixel_size(float pixel_size)72    void set_pixel_size(float pixel_size) { pixel_size_ = pixel_size; }
get_pixel_size()73    float get_pixel_size() const { return pixel_size_; }
74 
75    // Min and Max region intensities
get_min()76    float get_min() const { return min_; }
get_max()77    float get_max() const { return max_; }
78    //: reset the iterator for accessing region pixels
reset()79    void reset() const { pix_index_ = -1; }
80    //: increment to next pixel and check if iterator is finished
next()81    bool next() const {
82      ++pix_index_;
83      return pix_index_ < (int)npts_; }
84   float X() const;    //!< The x pixel coordinate
85   float Y() const;    //!< The y pixel coordinate
86   unsigned short I() const;//!< The pixel intensity
87 
88   void set_X(float x);    //!< change x pixel coordinate
89   void set_Y(float y);    //!< change y pixel coordinate
90   void set_I(unsigned short I);    //!< change pixel intensity
91 
92   // The mean geometric and intensity values of the region
93   float Xo() const; //!< The mean X value of the region
94   float Yo() const; //!< The mean Y value of the region
95   float Io() const; //!< The mean intensity value of the region
96   float Io_sd() const; //!< The intensity standard deviation value of the region
97   float ComputeIntensityStdev(); //!< Compute the intensity stdev for the region
98 
99   // Scatter Matrix Values
100   double X2() const; //!< The second order X moment of the region
101   double Y2() const; //!< The second order Y moment of the region
102   double XY() const; //!< The second order X,Y moment of the region
103   double I2() const; //!< The second order intensity moment of the region
104   double XI() const; //!< The second order X,intensity moment of the region
105   double YI() const; //!< The second order Y,intensity moment of the region
106   // Quantities computable from the region scatter matrix
107   float Diameter() const;
108   float AspectRatio() const;
109 
110   // distinguish from vtol_face::area()
area()111   double area() const override { return npts_*pixel_size_*pixel_size_; }
112 
113   //: The centroid of the pointset
centroid()114   vsol_point_2d_sptr centroid() const override
115     {return new vsol_point_2d(this->Xo(), this->Yo());}
116 
117   //: transform this region using the given 3x3 projective transformation matrix
118   bool transform(vnl_float_3x3 const& t);
119 
120   //: Compute the intensity histogram
121   //  The intensity ranges from get_min() to get_max().
122   std::vector<unsigned int> histogram(int nbins);
123   //: Compute the residual intensity histogram
124   //  The intensity range is returned as the last two arguments.
125   std::vector<unsigned int> residual_histogram(int nbins, float* min=nullptr, float* max=nullptr) const;
126 
127   //: Return true if this region is convex
is_convex()128   bool is_convex() const override { return false; } // virtual of vsol_region_2d
129 
130   bool PrincipalOrientation(vnl_float_2& major_axis);
131 
132   //Get Fitted Plane Coefficients
133   double Ix() const;  //!< First derivative of intensity wrt x
134   double Iy() const;  //!< First derivative of intensity wrt y
Var()135   double Var() const {return sigma_sq_;} //!< The plane fitting error.
136   float Ir() const;   //!< The pixel intensity with the plane subtracted
137 
138   // Utility Methods
139   void DoPlaneFit() const; //!< Fit a plane to the region intensities
140   void PrintFit() const;
141 
142   vsol_spatial_object_2d* clone() const override;
143 
144   //: Return a platform independent string identifying the class
is_a()145   std::string is_a() const override { return std::string("vdgl_digital_region"); }
146 
147  protected:
148   // Members
149    bool npts_given_{false}; //!< Creating a region with specified npts
150    unsigned int npts_{0};   //!< Number of pixels in the region
151    float pixel_size_{1.f};  //!< Image pixel size in fractions of a pixel
152    float *xp_{nullptr}, *yp_{nullptr}; //!< The location of each pixel
153    unsigned short *pix_{nullptr};      //!< The pixel intensities
154    float max_{0}, min_;                //!< Upper and lower bounds
155    float xo_{0.f}, yo_{0.f}, io_{0.f}; //!< Mean Values
156    float io_stdev_{0.0f};     //!< Intensity standard deviation for region
157    mutable int pix_index_{0}; //!< Index in pixel array (iterator)
158    void ComputeScatterMatrix() const;                    // mutable
159    void IncrByXYI(double x, double y, int intens) const; // mutable
160    double ComputeSampleResidual() const;                 // mutable
161    // members
162    mutable bool fit_valid_{false}; //!< Has a plane fit been done?
163    mutable bool scatter_matrix_valid_{
164        false};         //!< Is the scatter matrix current?
165    mutable double Ix_; //!< dI/dx
166    mutable double Iy_; //!< dI/dy
167    //: The sums of various monomials to form the scatter matrix
168    mutable double X2_{0}, Y2_{0}, I2_{0}, XY_{0}, XI_{0}, YI_{0};
169    mutable double error_{0}, sigma_sq_{0}; //!< fitting errors
170    mutable vnl_double_3x3 Si_;             //!< scatter matrix
171 };
172 #include "vdgl_digital_region_sptr.h"
173 //: merge regions - set the pixel arrays no statistics computed
174 //: pointer interface useful for merging subclasses of vdgl_digital_region. User must create r12.
175 //
176 void merge(vdgl_digital_region* r1, vdgl_digital_region * r2, vdgl_digital_region*& r12);
177 
178 // smart pointer interface - avoids copying return region. The return value is constructed internally
179 vdgl_digital_region_sptr merge(vdgl_digital_region_sptr const& r1, vdgl_digital_region_sptr const& r2);
180 #endif // vdgl_digital_region_h_
181