basic/geometry/IGS/IGS_ImageFloat1.cpp

Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <direct.h>
00003 #include "IGS_ImageFloat1.h"
00004 #include <list>
00005 #include <math.h>
00006 
00007 //=============================================================================
00008 // constructor
00009 //
00010 // Description: constructor
00011 //=============================================================================
00012 IGS_ImageFloat1::IGS_ImageFloat1():
00013         pixels( NULL )
00014 {
00015         IGS_Image::SetType( GL_FLOAT );
00016 }
00017 
00018 //=============================================================================
00019 // Destructor
00020 //
00021 // Description: destructor
00022 //=============================================================================
00023 IGS_ImageFloat1::~IGS_ImageFloat1()
00024 {
00025         this->Invalidate();
00026 }
00027 
00028 //=============================================================================
00029 // AddBorder
00030 //
00031 // Description: adds a border along the top bottom left and right of theimage
00032 //=============================================================================
00033 void IGS_ImageFloat1::AddBorder( const int width, const float value )
00034 {
00035         int i;
00036         for( i = 0; i < this->GetSizeX(); i++ )
00037         {
00038                 int w;
00039                 for( w = 0; w < width; w++ )
00040                 {
00041                         this->PutPixel( i, w, value );
00042                         this->PutPixel( i, this->GetSizeY() - 1 - w, value );
00043                 }
00044         }
00045 
00046         int j;
00047         for( j = 0; j < this->GetSizeY(); j++ )
00048         {
00049                 int w;
00050                 for( w = 0; w < width; w++ )
00051                 {
00052                         this->PutPixel( w, j, value );
00053                         this->PutPixel( this->GetSizeX() - 1 - w, j,  value );
00054                 }
00055         }
00056 }
00057 
00058 //=============================================================================
00059 // FileSave
00060 //
00061 // Description: save the file to disk
00062 //=============================================================================
00063 void IGS_ImageFloat1::FileSave( const char* filename ) const
00064 {
00065         FILE* outfile = fopen( filename, "wb" );
00066         char header[] = "IGS_FL1X";
00067         fwrite( header, strlen( header ), 1, outfile );
00068         fwrite( &sizeX, sizeof( int ), 1, outfile );
00069         fwrite( &sizeY, sizeof( int ), 1, outfile );
00070         int size = this->ComputeMaxIndex();
00071         fwrite( pixels, sizeof( float ), size, outfile );
00072         fclose( outfile );
00073 }
00074 
00075 //=============================================================================
00076 // FileLoad
00077 //
00078 // Description: load the file from disk
00079 //=============================================================================
00080 void IGS_ImageFloat1::FileLoad( const char* filename )
00081 {
00082         char directoryName[ 256 ] = "";
00083         ::_getcwd( directoryName, 256 );
00084         FILE* infile = fopen( filename, "rb" );
00085         assert( infile != NULL );
00086         char header[ 9 ] = "";
00087         fread( header, sizeof( char ), 8, infile );
00088         fread( &sizeX, sizeof( int ), 1, infile );
00089         fread( &sizeY, sizeof( int ), 1, infile );
00090         this->Initialize();
00091         int size = this->ComputeMaxIndex();
00092         fread( pixels, sizeof( float ), size, infile );
00093 }
00094 
00095 
00096 //=============================================================================
00097 // FindMax
00098 //
00099 // Description: finds the maximum value of the image
00100 //=============================================================================
00101 void IGS_ImageFloat1::FindMax( int& xMax, int& yMax, float absoluteMax ) const
00102 {
00103         xMax = yMax = 0;
00104         float max = this->GetPixel( 0, 0 );
00105         int i;
00106         for( i = 0; i < this->sizeX; i++ )
00107         {
00108                 int j;
00109                 for( j = 0; j < this->sizeY; j++ )
00110                 {
00111                         float check = this->GetPixel( i, j );
00112                         if( check > max )
00113                         {
00114                                 max = check;
00115                                 xMax = i;
00116                                 yMax = j;
00117                                 if( max >= absoluteMax )
00118                                 {
00119                                         return;
00120                                 }
00121                         }
00122                 }
00123         }
00124 }
00125 
00126 //=============================================================================
00127 // GetBuffer
00128 //
00129 // Description: gets a pointer to the underlying buffer
00130 //=============================================================================
00131 const void* const IGS_ImageFloat1::GetBuffer() const
00132 {
00133         return this->pixels;
00134 }
00135 
00136 
00137 //=============================================================================
00138 // GetBuffer
00139 //
00140 // Description: gets a pointer to the underlying buffer
00141 //=============================================================================
00142 void*& IGS_ImageFloat1::GetBuffer()
00143 {
00144         return reinterpret_cast< void*& >( this->pixels );
00145 }       
00146 
00147 //=============================================================================
00148 // GetPixel
00149 //
00150 // Description: gets a pixel from the image
00151 //=============================================================================
00152 void IGS_ImageFloat1::GetGradient( const int x, const int y, float& xg, float& yg )
00153 {
00154         xg = yg = 0;
00155 /*      static float horizontalEdge[] = 
00156         {
00157                 0,              0,              0,              0,              0,
00158                 0,              -1,             0,              1,              0,
00159                 0,              -2,             0,              2,              0,
00160                 0,              -1,             0,              1,              0,
00161                 0,              0,              0,              0,              0,
00162         };
00163 
00164         static float verticalEdge[] = 
00165         {
00166                 0,              0,              0,              0,              0,
00167                 0,              1,              2,              1,              0,
00168                 0,              0,              0,              0,              0,
00169                 0,              -1,             -2,             -1,             0,
00170                 0,              0,              0,              0,              0,
00171         };
00172 */
00173         static float horizontalEdge[] = 
00174         {
00175                 0,              -1,             0,              1,              0,
00176                 -1,             -4,             0,              4,              1,
00177                 -2,             -6,             0,              6,              2,
00178                 -1,             -4,             0,              4,              1,
00179                 0,              -1,             0,              1,              0,
00180         };
00181 
00182         static float verticalEdge[] = 
00183         {
00184                 0,              1,              2,              1,              0,
00185                 1,              4,              6,              4,              1,
00186                 0,              0,              0,              0,              0,
00187                 -1,             -4,             -6,             -4,             -1,
00188                 0,              -1,             -2,             -1,             0,
00189         };
00190 
00191         float hImage[] = 
00192         {
00193                 this->GetPixel( x - 2, y + 2 ), this->GetPixel( x - 1, y + 2 ), this->GetPixel( x, y + 1 ) ,this->GetPixel( x + 1, y + 2 ), this->GetPixel( x + 1, y + 2 ),
00194                 this->GetPixel( x - 2, y + 1 ), this->GetPixel( x - 1, y + 1 ), this->GetPixel( x, y + 1 ) ,this->GetPixel( x + 1, y + 1 ), this->GetPixel( x + 1, y + 1 ),
00195                 this->GetPixel( x - 2, y + 0 ), this->GetPixel( x - 1, y + 0 ), this->GetPixel( x, y + 0 ) ,this->GetPixel( x + 1, y + 1 ), this->GetPixel( x + 1, y + 0 ),
00196                 this->GetPixel( x - 2, y - 1 ), this->GetPixel( x - 1, y - 1 ), this->GetPixel( x, y - 1 ) ,this->GetPixel( x + 1, y - 1 ), this->GetPixel( x + 1, y - 1 ),
00197                 this->GetPixel( x - 2, y - 2 ), this->GetPixel( x - 1, y - 2 ), this->GetPixel( x, y - 2 ) ,this->GetPixel( x + 1, y - 2 ), this->GetPixel( x + 1, y - 2 ),
00198         };
00199 
00200         int i;
00201         for( i = 0; i < 25; i++ )
00202         {
00203                 xg += horizontalEdge[ i ] * hImage[ i ];
00204                 yg += verticalEdge[ i ] * hImage[ i ];
00205         }
00206         float mag = sqrt( xg * xg + yg * yg );
00207         if( mag == 0 )
00208         {
00209                 xg = 1;
00210                 yg = 0;
00211         }
00212         else
00213         {
00214                 assert( mag != 0 );
00215                 xg /= mag;
00216                 yg /= mag;
00217         }
00218 }
00219 
00220 //=============================================================================
00221 // GetPixel
00222 //
00223 // Description: gets a pixel from the image
00224 //=============================================================================
00225 float IGS_ImageFloat1::GetPixel( const int x, const int y ) const
00226 {
00227         int index = this->ComputeIndex( x, y );
00228         float* fpixels = reinterpret_cast< float* >( pixels );
00229         float& value = fpixels[ index ];
00230         return value;
00231 }
00232 
00233 //=============================================================================
00234 // GetPixelFloat1
00235 //
00236 // Description: returns a floating point value of that pixel
00237 //=============================================================================
00238 float IGS_ImageFloat1::GetPixelFloat1( const int x ,const int y ) const
00239 {
00240         assert( false );
00241         return 0;
00242 }
00243 
00244 //=============================================================================
00245 // Initialize
00246 //
00247 // Description: initializes the image
00248 //=============================================================================
00249 void IGS_ImageFloat1::Initialize()
00250 {
00251         this->semaphore.Lock();
00252         int sizeOfData = IGS_Image::SizeOfType( this->type );
00253         if( pixels != NULL )
00254         {
00255                 delete[] pixels;
00256         }
00257         pixels = new float[ this->sizeX * this->sizeY * sizeOfData ];
00258         this->semaphore.Unlock();
00259 }       
00260 
00261 //=============================================================================
00262 // OperationIncrease
00263 //
00264 // Description: adds a constant factor to each pixel
00265 //=============================================================================
00266 void IGS_ImageFloat1::OperationAbs()
00267 {
00268         int maxIndex = this->ComputeMaxIndex();
00269         int i;
00270         for( i = 0; i < maxIndex; i++ )
00271         {
00272                 pixels[ i ] = static_cast< float >( fabs( pixels[ i ] ) );
00273         }
00274 }
00275 
00276 //=============================================================================
00277 // OperationDilate
00278 //
00279 // Description: dilates the image
00280 //=============================================================================
00281 void IGS_ImageFloat1::OperationBlur()
00282 {
00283         static float blur[] =   
00284         {
00285                 0,              1,              0,
00286                 1,              2,              1,
00287                 0,              1,              0,
00288         };
00289 
00290         IGS_FilterMatrixFloat blurFilter( 3, 3, blur );
00291         blurFilter.Normalize();
00292         IGS_ImageFloat1 intermediate;
00293         this->OperationFilter( blurFilter, intermediate );
00294         *this = intermediate;
00295 }
00296 
00297 //=============================================================================
00298 // OperationDilate
00299 //
00300 // Description: dilates the image
00301 //=============================================================================
00302 struct XYpair
00303 {
00304         int x;
00305         int y;
00306 };
00307 
00308 void IGS_ImageFloat1::OperationDilate( const float maxRadius )
00309 {
00310         std::list< XYpair > points;
00311         points.clear();
00312 
00313         XYpair coords;
00314         float increment = 1.0f/256;
00315         float diagonalIncrement = increment * 1.41;
00316 
00317         //go through and find all the initial coords
00318         for( coords.x = 0; coords.x < this->GetSizeX() - 5; coords.x++ )
00319         {
00320                 for( coords.y = 0; coords.y < this->GetSizeY() - 5; coords.y++ )
00321                 {
00322                         if( this->GetPixel( coords.x, coords.y ) == 0 )
00323                         {
00324                                 assert( coords.x < this->GetSizeX() );
00325                                 assert( coords.y < this->GetSizeY() );
00326                                 points.push_back( coords );
00327                         }
00328                 }
00329         }
00330 
00331         std::list< XYpair>::iterator it = points.begin();
00332         while( it != points.end() )
00333         {
00334                 XYpair& point = *it;
00335                 float value = this->GetPixel( point.x, point.y );
00336                 if( value < maxRadius )
00337                 {
00338 
00339                         //add adjacent points
00340                         //do left
00341                         if( point.x != 0 )
00342                         {
00343                                 float currentValue = this->GetPixel( point.x - 1, point.y );
00344                                 if( ( currentValue > value + increment ) )
00345                                 {
00346                                         XYpair left;
00347                                         left.x = point.x - 1;
00348                                         left.y = point.y;
00349                                         this->PutPixel( left.x, left.y, value + increment );
00350                                         points.push_back( left );
00351                                 }
00352                         }
00353 
00354                         //do right
00355                         if( point.x != this->GetSizeX() - 1 )
00356                         {
00357                                 float currentValue = this->GetPixel( point.x + 1, point.y );
00358                                 if( ( currentValue > value + increment ) )
00359                                 {
00360                                         XYpair right;
00361                                         right.x = point.x + 1;
00362                                         right.y = point.y;
00363                                         this->PutPixel( right.x, right.y, value + increment );
00364                                         points.push_back( right );
00365                                 }
00366                         }
00367 
00368                         //do up
00369                         if( point.y != this->GetSizeY() - 1 )
00370                         {
00371                                 float currentValue = this->GetPixel( point.x, point.y + 1 );
00372                                 if( ( currentValue > value + increment ) )
00373                                 {
00374                                         XYpair right;
00375                                         right.x = point.x;
00376                                         right.y = point.y + 1;
00377                                         this->PutPixel( right.x, right.y, value + increment );
00378                                         points.push_back( right );
00379                                 }
00380                         }
00381 
00382                         //do down
00383                         if( point.y != 0 )
00384                         {
00385                                 float currentValue = this->GetPixel( point.x, point.y - 1 );
00386                                 if( ( currentValue > value + increment ) )
00387                                 {
00388                                         XYpair right;
00389                                         right.x = point.x;
00390                                         right.y = point.y - 1;
00391                                         this->PutPixel( right.x, right.y, value + increment );
00392                                         points.push_back( right );
00393                                 }
00394                         }
00395 
00396                         //do lower left
00397                         if( ( point.y != 0 ) && ( point.x != 0 ) )
00398                         {
00399                                 float currentValue = this->GetPixel( point.x - 1, point.y - 1 );
00400                                 if( ( currentValue > value + diagonalIncrement )  )
00401                                 {
00402                                         XYpair right;
00403                                         right.x = point.x - 1;
00404                                         right.y = point.y - 1;
00405                                         this->PutPixel( right.x, right.y, value + diagonalIncrement );
00406                                         points.push_back( right );
00407                                 }
00408                         }
00409 
00410                         //do upper left
00411                         if( ( point.y != 0 ) && ( point.x != 0 ) )
00412                         {
00413                                 float currentValue = this->GetPixel( point.x - 1, point.y + 1 );
00414                                 if( ( currentValue > value + diagonalIncrement )  )
00415                                 {
00416                                         XYpair right;
00417                                         right.x = point.x - 1;
00418                                         right.y = point.y + 1;
00419                                         this->PutPixel( right.x, right.y, value + diagonalIncrement );
00420                                         points.push_back( right );
00421                                 }
00422                         }
00423 
00424                         //do upper right
00425                         if( ( point.y != 0 ) && ( point.x != 0 ) )
00426                         {
00427                                 float currentValue = this->GetPixel( point.x + 1, point.y + 1 );
00428                                 if( ( currentValue > value + diagonalIncrement )  )
00429                                 {
00430                                         XYpair right;
00431                                         right.x = point.x + 1;
00432                                         right.y = point.y + 1;
00433                                         this->PutPixel( right.x, right.y, value + diagonalIncrement );
00434                                         points.push_back( right );
00435                                 }
00436                         }
00437 
00438                         //do lower right
00439                         if( ( point.y != 0 ) && ( point.x != 0 ) )
00440                         {
00441                                 float currentValue = this->GetPixel( point.x + 1, point.y - 1 );
00442                                 if( ( currentValue > value + diagonalIncrement )  )
00443                                 {
00444                                         XYpair right;
00445                                         right.x = point.x + 1;
00446                                         right.y = point.y - 1;
00447                                         this->PutPixel( right.x, right.y, value + diagonalIncrement );
00448                                         points.push_back( right );
00449                                 }
00450                         }
00451 
00452                 }
00453                 points.pop_front();
00454                 it = points.begin();
00455         }
00456 }
00457 
00458 //=============================================================================
00459 // OperationIncrease
00460 //
00461 // Description: adds a constant factor to each pixel
00462 //=============================================================================
00463 void IGS_ImageFloat1::OperationIncrease( const float f )
00464 {
00465         int maxIndex = this->ComputeMaxIndex();
00466         int i;
00467         for( i = 0; i < maxIndex; i++ )
00468         {
00469                 pixels[ i ] += f;
00470         }
00471 }
00472 
00473 //=============================================================================
00474 // OperationIncrease
00475 //
00476 // Description: adds a constant factor to each pixel
00477 //=============================================================================
00478 void IGS_ImageFloat1::OperationInvert()
00479 {
00480         int maxIndex = this->ComputeMaxIndex();
00481         int i;
00482         for( i = 0; i < maxIndex; i++ )
00483         {
00484                 pixels[ i ] = 1 - pixels[ i ];
00485         }
00486 }
00487 
00488 //=============================================================================
00489 // OperationScale
00490 //
00491 // Description: scales a floating point image by a constant factor
00492 //=============================================================================
00493 void IGS_ImageFloat1::OperationFilter( const IGS_FilterMatrixFloat f, IGS_ImageFloat1& output )
00494 {
00495         //setup size of output image
00496         output.SetResolution( this->sizeX, this->sizeY );
00497         output.Initialize();
00498 
00499         int i;
00500         for( i = 0; i < this->sizeX - f.mSizeX; i++ )
00501         {
00502                 int j;
00503                 for( j = 0; j < this->sizeY - f.mSizeY; j++ )
00504                 {
00505                         float outputvalue = 0;
00506                         int u;
00507                         for( u = 0; u < f.mSizeX; u++ )
00508                         {
00509                                 int v;
00510                                 for( v = 0; v < f.mSizeY; v++ )
00511                                 {
00512                                         float filter = f.GetValue( u, v );
00513                                         float input = this->GetPixel( i + u, j + v );
00514                                         outputvalue += filter * input;
00515                                 }
00516                         }
00517                         output.PutPixel( i, j, outputvalue );
00518                 }
00519         }
00520 }
00521 
00522 //=============================================================================
00523 // OperationRangeStretch
00524 //
00525 // Description: stretches values in a range
00526 //=============================================================================
00527 void IGS_ImageFloat1::OperationRangeStretch( const float low, const float hi )
00528 {
00529         int maxIndex = this->ComputeMaxIndex();
00530         float range = hi - low;
00531         assert( range != 0 );
00532         int i;
00533         for( i = 0; i < maxIndex; i++ )
00534         {
00535                 float& value = pixels[ i ];
00536                 if( value < low )
00537                 {
00538                         value = 0;
00539                 }
00540                 else if( value > hi )
00541                 {
00542                         value = 1;
00543                 }
00544                 else
00545                 {
00546                         pixels[ i ] = ( value - low ) / range;
00547                 }
00548         }
00549 }
00550 
00551 
00552 //=============================================================================
00553 // OperationScale
00554 //
00555 // Description: scales a floating point image by a constant factor
00556 //=============================================================================
00557 void IGS_ImageFloat1::OperationScale( const float f )
00558 {
00559         int maxIndex = this->ComputeMaxIndex();
00560         int i;
00561         for( i = 0; i < maxIndex; i++ )
00562         {
00563                 pixels[ i ] *= f;
00564         }
00565 }
00566 
00567 //=============================================================================
00568 // OperationScale
00569 //
00570 // Description: scales a floating point image by a constant factor
00571 //=============================================================================
00572 void IGS_ImageFloat1::OperationThreshold( const float f )
00573 {
00574         int maxIndex = this->ComputeMaxIndex();
00575         int i;
00576         for( i = 0; i < maxIndex; i++ )
00577         {
00578                 if( pixels[ i ] > f )
00579                 {
00580                         pixels[ i ] = 1;
00581                 }
00582                 else
00583                 {
00584                         pixels[ i ] = 0;
00585                 }
00586         }
00587 }
00588 
00589 //=============================================================================
00590 // operator*=
00591 //
00592 // Description: in place multiplication
00593 //=============================================================================
00594 IGS_ImageFloat1& IGS_ImageFloat1::operator*=( const IGS_ImageFloat1& right )
00595 {
00596         assert( this->GetSizeX() == right.GetSizeX() );
00597         assert( this->GetSizeY() == right.GetSizeY() );
00598         int i;
00599         int max = this->ComputeMaxIndex();
00600         for( i = 0; i < max; i++ )
00601         {
00602                 this->pixels[ i ] *= right.pixels[ i ];
00603         }
00604         return *this;
00605 }
00606 
00607 //=============================================================================
00608 // operator*=
00609 //
00610 // Description: in place scalar multiplication
00611 //=============================================================================
00612 IGS_ImageFloat1& IGS_ImageFloat1::operator*=( const float f )
00613 {
00614         this->OperationScale( f );
00615         return *this;
00616 }
00617 
00618 //=============================================================================
00619 // operator+=
00620 //
00621 // Description: in place addition
00622 //=============================================================================
00623 IGS_ImageFloat1& IGS_ImageFloat1::operator+=( const IGS_ImageFloat1& right )
00624 {
00625         assert( this->GetSizeX() == right.GetSizeX() );
00626         assert( this->GetSizeY() == right.GetSizeY() );
00627         int i;
00628         int max = this->ComputeMaxIndex();
00629         for( i = 0; i < max; i++ )
00630         {
00631                 this->pixels[ i ] += right.pixels[ i ];
00632         }
00633         return *this;
00634 }
00635 
00636 //=============================================================================
00637 // operator=
00638 //
00639 // Description: assignment operator
00640 //=============================================================================
00641 IGS_ImageFloat1& IGS_ImageFloat1::operator=( const IGS_ImageChannel1& right )
00642 {
00643         if( ( this->GetSizeX() != right.GetSizeX() ) || ( this->GetSizeY() != right.GetSizeY() ) )
00644         {
00645                 //need to resize this image
00646                 this->SetResolution( right.GetSizeX(), right.GetSizeY() );
00647                 this->Initialize();
00648         }
00649 
00650         int x;
00651         for( x = 0; x < this->GetSizeX(); x++ )
00652         {
00653                 int y;
00654                 for( y = 0; y < this->GetSizeY(); y++ )
00655                 {
00656                         float value = right.GetPixelFloat1( x, y );
00657                         this->PutPixel( x, y, value );
00658                 }
00659         }
00660         return *this;
00661 }
00662 
00663 //=============================================================================
00664 // operator=
00665 //
00666 // Description: assignment operator
00667 //=============================================================================
00668 IGS_ImageFloat1& IGS_ImageFloat1::operator=( const IGS_ImageFloat1& right )
00669 {
00670         if( ( this->GetSizeX() != right.GetSizeX() ) || ( this->GetSizeY() != right.GetSizeY() ) )
00671         {
00672                 //need to resize this image
00673                 this->SetResolution( right.GetSizeX(), right.GetSizeY() );
00674                 this->Initialize();
00675         }
00676         
00677         int size = this->ComputeMaxIndex() * sizeof( float );
00678         memcpy( this->pixels, right.pixels, size );
00679         return *this;
00680 }
00681 
00682 //=============================================================================
00683 // operator=
00684 //
00685 // Description: assignment operator
00686 //=============================================================================
00687 IGS_ImageFloat1& IGS_ImageFloat1::operator=( const float right )
00688 {
00689         int i;
00690         int max = this->ComputeMaxIndex();
00691         for( i = 0; i < max; i++ )
00692         {
00693                 this->pixels[ i ] = right;
00694         }
00695         return *this;
00696 }
00697 
00698 
00699 //=============================================================================
00700 // GetPixel
00701 //
00702 // Description: gets a pixel from the image
00703 //=============================================================================
00704 void IGS_ImageFloat1::PutPixel( const int x, const int y, float newValue )
00705 {
00706         int index = this->ComputeIndex( x, y );
00707         float* fpixels = reinterpret_cast< float* >( pixels );
00708         float& value = fpixels[ index ];
00709         value = newValue;
00710 }
00711 
00712 //=============================================================================
00713 // PutPixelFloat1
00714 //
00715 // Description: puts a floating point value into the image (1 channel )
00716 //=============================================================================
00717 void IGS_ImageFloat1::PutPixelFloat1( const int x, const int y, const float value )
00718 {
00719         assert( false );
00720 }

Generated on Sat Apr 1 21:30:32 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO