00001 #include <assert.h>
00002 #include <direct.h>
00003 #include "IGS_ImageFloat1.h"
00004 #include <list>
00005 #include <math.h>
00006
00007
00008
00009
00010
00011
00012 IGS_ImageFloat1::IGS_ImageFloat1():
00013 pixels( NULL )
00014 {
00015 IGS_Image::SetType( GL_FLOAT );
00016 }
00017
00018
00019
00020
00021
00022
00023 IGS_ImageFloat1::~IGS_ImageFloat1()
00024 {
00025 this->Invalidate();
00026 }
00027
00028
00029
00030
00031
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
00060
00061
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
00077
00078
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
00098
00099
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
00128
00129
00130
00131 const void* const IGS_ImageFloat1::GetBuffer() const
00132 {
00133 return this->pixels;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 void*& IGS_ImageFloat1::GetBuffer()
00143 {
00144 return reinterpret_cast< void*& >( this->pixels );
00145 }
00146
00147
00148
00149
00150
00151
00152 void IGS_ImageFloat1::GetGradient( const int x, const int y, float& xg, float& yg )
00153 {
00154 xg = yg = 0;
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
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
00222
00223
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
00235
00236
00237
00238 float IGS_ImageFloat1::GetPixelFloat1( const int x ,const int y ) const
00239 {
00240 assert( false );
00241 return 0;
00242 }
00243
00244
00245
00246
00247
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
00263
00264
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
00278
00279
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
00299
00300
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
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
00340
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
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
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
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
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
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
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
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
00460
00461
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
00475
00476
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
00490
00491
00492
00493 void IGS_ImageFloat1::OperationFilter( const IGS_FilterMatrixFloat f, IGS_ImageFloat1& output )
00494 {
00495
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
00524
00525
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
00554
00555
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
00569
00570
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
00591
00592
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
00609
00610
00611
00612 IGS_ImageFloat1& IGS_ImageFloat1::operator*=( const float f )
00613 {
00614 this->OperationScale( f );
00615 return *this;
00616 }
00617
00618
00619
00620
00621
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
00638
00639
00640
00641 IGS_ImageFloat1& IGS_ImageFloat1::operator=( const IGS_ImageChannel1& right )
00642 {
00643 if( ( this->GetSizeX() != right.GetSizeX() ) || ( this->GetSizeY() != right.GetSizeY() ) )
00644 {
00645
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
00665
00666
00667
00668 IGS_ImageFloat1& IGS_ImageFloat1::operator=( const IGS_ImageFloat1& right )
00669 {
00670 if( ( this->GetSizeX() != right.GetSizeX() ) || ( this->GetSizeY() != right.GetSizeY() ) )
00671 {
00672
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
00684
00685
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
00701
00702
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
00714
00715
00716
00717 void IGS_ImageFloat1::PutPixelFloat1( const int x, const int y, const float value )
00718 {
00719 assert( false );
00720 }