#ifndef BaseRange_HH #define BaseRange_HH //////////////////////////////////////////////////////////////////////////// //! author="Robert Crida" lib=Range //! date="30/5/96" //! userlevel=Develop //! file="amma/Surf3d/Range/BaseRange.hh" //! lib=Range //! rcsid="$Id: BaseRange.hh,v 1.25 1999/03/29 11:17:19 ees1cg Exp $" //! docentry="default.Robert Crida" #include #include "amma/ByteImag.hh" #include "amma/Vector3d.hh" #include "amma/Polops.hh" #ifdef OUTLINE #define MyInline #else #define MyInline inline #endif // ------------------------------------------------------------------------- // ********** BaseRangeC ************************************************* // ------------------------------------------------------------------------- //: Base class for range images. // // BaseRangeC is a virtual abstract base class from which ByteRangeC, // FloatRangeC and VectRangeC will be inherited.

// // The i/o routines do have basic error checks.

// // A valid image point is one in which a range measurement is available. // How it is stored is dependent on the data structure but can be checked // by calling the function IsValid(). In byte format, 0 is invalid and // in vector format, z=-MAXFLOAT is invalid.

// // Range data is much more complicated than image data. It can be // sampled on a regular grid or not, the grid spacings may vary. // Together ByteRangeC, FloatRangeC and VectRangeC provide a powerful // set of functionality. For accurate results it is important to understand // precisely how the system is set up.

// // Firstly we explain the conventions for "gridded data". Consider a // 4 pixel image row or column.

// //

// ---   <-- 0.0    xgridmin=0.0
// |                 ____ box center = 0.5
// |              
// ___   <-- 1.0
// |
// |
// ___   <-- 2.0
// |
// |
// ___   <-- 3.0    xgridmax=3.0
// |
// |
// ___   <-- 4.0
// 
// // There are nrows=4 rows, i.e. r=0..3=nrows-1. Each bin hase size 1 // and the total range is 0.0 - 3.9999999. // For gridded data the pixels are deemed to be in the centers of the boxes, // i.e. at 0.5, 1.5, 2.5, 3.5.

// // With each range image, the minimum and maximum x, y and z values are // stored. In each case, the values are obtained by scanning all of the // valid image points and finding the extremes in each dimension. These // values are kept in xmin,xmax,ymin,ymax,zmin,zmax.

// // For conversions between row and column and x and y we use // gridxmin,gridxmax,gridymin,gridymax. They are defined as shown above in the // picture. In this example

// //

// For gridded data the xgridmin=0.0  xgridmax=3.0,
//                      xmin=0.5      xmax=3.5      
// asuming valid pixels in the border rows.
// 
// // These values are obtained if possible from the data file.

// // To summarize the conversion is as follows:

// // gridsize.X = (gridmax.X - gridmin.X) / (ncols-1) // //

// PixelC OfVect(const Vector3dC vect) const
// {
//   return PixelC (int(floor((vect.Y()-gridmin.Y())/gridsize.Y())),
//                  int(floor((vect.X()-gridmin.X())/gridsize.X())));
// }
//
// Vector3dC GetVect(const PixelC & pxl) const
// {
//   return Vector3dC ((pxl.Col()+0.5)*gridsize.X()+gridmin.X(), 
//                     (pxl.Row()+0.5)*gridsize.Y()+gridmin.Y(), 
//                     f_data[pxl]);
// }
// 
// // The conversion from to a ByteRangeC uses the same scheme for z noting that // the range of valid pixels is 1..255, "nrows"=255.

// // A vector range image may contain any vector in any pixel. If the // operation MaptoGrid is called, however each pixel must contain a // vector in the bin.

// // Any conversion from a vector representation will result in a rounding // down of the x and y values to the grid positions. To compensate for this // conversion from byte to vector will round up the positions to the centre // of the grid boxes.

// // All loads are soft except Load, soft means no exit on error.

// // A left hand coordinate system is used with x and y increasing horizontally // and vertically, respectively (col,row). z increases away from the camera // with the result that when viewed using normal image viewers, greater // distances will appear brighter unless photometric inversion is employed.

// // Files that can be read .pgm .dep .ris .nrcc .txt .vec .jrc .XYZim

// // Files that can be written .pgm .dep .ris

class BaseRangeC { protected: #if defined(VISUAL_CPP) || defined(__sgi__) || defined(NEWGCC) static const double DefaultMax; static const double DefaultMin; #else const double DefaultMax = -1e38; const double DefaultMin = 1e38; #endif int nrows, ncols; Vector3dC min,max; Vector3dC gridmin,gridmax; Vector3dC gridsize; int isgridded; void ExtremesForSubImage (const ImageRectangleC & rect); //: Calculates new grid extreme values // Determined using the spacing and ratios of the overall size virtual BooleanT TestFace(const Vector3dC& v0,const Vector3dC& v1, const Vector3dC& v2,const RealT min_cos_angle); //: Test if cos angle of face normal to z-axis is > min_cos_angle virtual void InsertFace(IntT& counter, ImageC& countimage, DListC& v_list, DListC& f_list, const PixelC p0,const PixelC p1, const PixelC p2); //: function used in ExportPol2 to insert a triangle in the mesh public: BaseRangeC (); //: Constructs an empty Range image BaseRangeC (int rows, int cols); //: Constructs a Range with space allocated BaseRangeC (const BaseRangeC & range); //: Copy constructor BaseRangeC & operator= (const BaseRangeC & range); //: Assignment virtual ~BaseRangeC (); //: Destructor //!section: Access to parameters /*----------------------------*/ MyInline int NRows () const; //: Access number of rows MyInline int NCols () const; //: Access number of cols MyInline Vector3dC Min () const; //: Access minimum corner of bounding box MyInline Vector3dC Max () const; //: Access maximum corner of bounding box MyInline Vector3dC GridMin () const; //: Access minimum corner of grid bounding box MyInline Vector3dC GridMax () const; //: Access maximum corner of grid bounding box MyInline Vector3dC GridSize () const; //: Access spacing of the grid virtual MyInline ByteGreyValueT GetByteZ (const PixelC & pxl) const=0; //: Access depth given position virtual MyInline float GetFloatZ (const PixelC &pxl) const=0; //: Access depth given position virtual MyInline Vector3dC GetVect (const PixelC & pxl) const=0; //: Access vector given grid position virtual MyInline void PutByteZ (const PixelC & pxl, ByteGreyValueT z) =0; //: Set depth at given position virtual MyInline void PutFloatZ (const PixelC &pxl, float z) =0; //: Set depth at a given position virtual MyInline void PutVect (const PixelC & pxl, Vector3dC vect) =0; //: Set vector at given position virtual MyInline void PutVect (const Vector3dC vect); //: Determines position in array and inserts vector. Must pass IsInside() virtual MyInline int IsValid (const PixelC &pixel) const=0; //: Determine whether given pixel is valid MyInline int IsInside (const Vector3dC vect) const; //: Determines whether a vector is within the grid extremes MyInline int IsInsideXY (const Vector3dC vect) const; //: Determines whether x,y of vect is within the grid extremes MyInline PixelC OfVect (const Vector3dC vect) const; //: Determines pixel position in array of a vector void SetXGridExtremes (double xmin, double xmax); //: Sets extremes and determines spacing void SetYGridExtremes (double ymin, double ymax); //: Sets extremes and determines spacing void SetZGridExtremes (double zmin, double zmax); //: Sets extremes and determines spacing //!section: Loading and Saving /*--------------------------*/ virtual int SoftLoad (char *fname) =0; //: load from any file, if error then return 0 else 1 virtual void Load (char *fname) =0; //: load from any file, if error then exit virtual int SoftSave (char *fname) =0; //: save to file, if error then return 0 else 1 virtual void Save (char *fname) =0; //: save to file virtual void CalculateExtremes (); //: Determines extreme values of x,y and z // This determines the max and min x,y,z values for the valid image points. // If the image is not gridded then grid min and max values are // extrapolated to give result that would be achieved if the invalid // points had been included in the calculation. //!section: Conversion to other representations /*-------------------------------------------*/ virtual ByteImageC ExportZasByte (int reversevideo = 0) =0; //: generate a byteimage of the z data virtual ByteImageC ExportDXasByte (); //: generate a byteimage of the x data virtual ByteImageC ExportDYasByte (); //: generate a byteimage of the y data virtual ByteImageC ExportValidasByte (); //: generate a byte image of the valid points virtual PolopsC ExportPol (double steepestslope = 100.0); //: generate a polops class of the data. // Steepest slope is a ratio of dz/sqrt(dx^2+dy*2) virtual PolopsC ExportPol2 (double steepestslope = 100.0); //: generate a triangulation mesh. // steepest slope is max angle of triangle to z-axis. // NB: Trianglation indexed without using Polops().Purify() for effieciency friend ostream & operator<<(ostream & s, const BaseRangeC & range); }; ostream & operator<<(ostream & s, const BaseRangeC & range); // ------------------------------------------------------------------------- //: do statement for each pixel of the range image #define FOREACH_RANGE_PIXEL(range,pxl) \ for(PixelC pxl(0,0); pxl.Row() < (range).NRows(); pxl.Row()++) \ for(pxl.Col() = 0; pxl.Col() < (range).NCols(); pxl.Col()++) // ------------------------------------------------------------------------- extern FILE *myfopen (char *fname); extern int myfclose (FILE *fptr, char *fname); extern double keyget (char * str, char * key); extern char *keyfind (char * str, char * key); #undef MyInline #ifndef OUTLINE #include "amma/BaseRange.icc" #endif #endif // ------------------------------------------------------------------------- // End of include file BaseRange.hh // -------------------------------------------------------------------------