redEye_internal.h File Reference

#include <qimage.h>
#include <qvaluestack.h>
#include <qpoint.h>

Include dependency graph for redEye_internal.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void findRegionOfInterest (QPoint topLeftExtreme, QPoint bottomRightExtreme)
void findBlobs ()
void pushPixel (int x, int y, int id)
void sortBlobsByDecreasingSize ()
void findBestTwoBlobs ()
void desaturateBlobs ()
void desaturateEntireImage (QPoint topLeftExtreme, QPoint bottomRightExtreme)
bool IDedPixel (int x, int y)
double desaturateAlpha (int x, int y)

Variables

StatusWidgetstatus
int updateIncrement
int newProgress
QImage rawImage
QImage * editedImage
QPoint topLeft
QPoint bottomRight
int regionWidth
int regionHeight
int blobPixelCount
QPoint blobTopLeft
QPoint blobBottomRight
int * regionOfInterest
QValueStack< QPoint > spreadablePixels
QValueStack< int > blobIDs
QValueStack< int > blobSizes
QValueStack< double > blobAspectRatios
int blobCount
int * ids
int * sizes
double * ratios
int id1
int id2


Function Documentation

double desaturateAlpha ( int  x,
int  y 
)

Definition at line 572 of file redEye.cpp.

References IDedPixel().

Referenced by desaturateBlobs().

00573 {
00574   int n = 0;
00575   if( IDedPixel(x  ,y  ) ) n++;
00576   
00577   if(n == 1)
00578     return 1.0;
00579   
00580   if( IDedPixel(x-1,y-1) ) n++;
00581   if( IDedPixel(x  ,y-1) ) n++;
00582   if( IDedPixel(x+1,y-1) ) n++;
00583   if( IDedPixel(x-1,y  ) ) n++;
00584   if( IDedPixel(x+1,y  ) ) n++;
00585   if( IDedPixel(x-1,y+1) ) n++;
00586   if( IDedPixel(x  ,y+1) ) n++;
00587   if( IDedPixel(x+1,y+1) ) n++;
00588   
00589   if( IDedPixel(x-2,y-2) ) n++;
00590   if( IDedPixel(x-1,y-2) ) n++;
00591   if( IDedPixel(x  ,y-2) ) n++;
00592   if( IDedPixel(x+1,y-2) ) n++;
00593   if( IDedPixel(x+2,y-2) ) n++;
00594   
00595   if( IDedPixel(x-2,y-1) ) n++;
00596   if( IDedPixel(x+2,y-1) ) n++;
00597   if( IDedPixel(x-2,y  ) ) n++;
00598   if( IDedPixel(x+2,y  ) ) n++;
00599   if( IDedPixel(x-2,y+1) ) n++;
00600   if( IDedPixel(x+2,y+1) ) n++;
00601   
00602   if( IDedPixel(x-2,y+2) ) n++;
00603   if( IDedPixel(x-1,y+2) ) n++;
00604   if( IDedPixel(x  ,y+2) ) n++;
00605   if( IDedPixel(x+1,y+2) ) n++;
00606   if( IDedPixel(x+2,y+2) ) n++;
00607   
00608   
00609   return ((double)n) / 25;
00610 }

void desaturateBlobs (  ) 

Definition at line 612 of file redEye.cpp.

References bottomRight, desaturateAlpha(), editedImage, and topLeft.

Referenced by removeRedeyeRegions().

00613 {
00614   //desaturate bad pixels
00615   int x, y;
00616   double r;
00617   QRgb* rgb;
00618   uchar* scanLine;
00619   for( y = QMAX( topLeft.y()-1, 0); 
00620        y<= QMIN( bottomRight.y()+1, editedImage->height()-1 ); 
00621        y++)
00622   {
00623     scanLine = editedImage->scanLine(y);
00624     for( x =  QMAX( topLeft.x()-1, 0); 
00625          x <= QMIN( bottomRight.x()+1, editedImage->width()-1 ); 
00626          x++)
00627     {      
00628       double alpha = desaturateAlpha( x, y );
00629       if( alpha > 0)
00630       {
00631         rgb = ((QRgb*)scanLine+x);
00632         
00633         r = alpha*(0.05*qRed(*rgb) + 0.6*qGreen(*rgb) + 0.3*qBlue(*rgb)) +
00634           (1-alpha)*qRed(*rgb);
00635         *rgb = qRgb( (int)r,
00636                      qGreen(*rgb),
00637                      qBlue(*rgb) );
00638       } //alpha > 0
00639     } //x
00640   } //y  
00641 }

void desaturateEntireImage ( QPoint  topLeftExtreme,
QPoint  bottomRightExtreme 
)

Definition at line 643 of file redEye.cpp.

References editedImage.

Referenced by removeRedeyeRegions().

00644 {
00645   //desaturate bad pixels
00646   int x, y;
00647   QRgb* rgb;
00648   uchar* scanLine;
00649   for( y=topLeftExtreme.y(); y<=bottomRightExtreme.y(); y++)
00650   {
00651     scanLine = editedImage->scanLine(y);
00652     for( x=topLeftExtreme.x(); x<=bottomRightExtreme.x(); x++)
00653     {
00654       rgb = ((QRgb*)scanLine+x);
00655       if( qRed(*rgb) > 2*qGreen(*rgb) )
00656       {
00657         *rgb = qRgb( (int) (0.05*qRed(*rgb) + 0.6*qGreen(*rgb) + 0.3*qBlue(*rgb)),
00658                      qGreen(*rgb),
00659                      qBlue(*rgb) );
00660       } // > thresh
00661     } //x
00662   } //y
00663 }

void findBestTwoBlobs (  ) 

Definition at line 506 of file redEye.cpp.

References blobCount, id1, id2, ids, ratios, and sizes.

Referenced by removeRedeyeRegions().

00507 {
00508   id1 = -1;
00509   id2 = -1;
00510   int i;
00511   
00512   //special case: 2 blobs found, both larger than 1 pixel
00513   if(blobCount == 2 &&
00514      sizes[0] > 1 &&
00515      sizes[1] > 1)
00516   {
00517     id1 = ids[0];
00518     id2 = ids[1];
00519   }
00520   else
00521   {
00522     for(i=0; i<blobCount-2; i++)
00523     {
00524       //once we hit blobs that are only one pixel large stop because they are probably just noise
00525       if( sizes[i+1] <= 1 ) break;
00526       
00527       double as1 = ratios[i];
00528       double as2 = ratios[i+1];
00529 
00530       if(as1 < 1) as1 = 1.0/as1;
00531       if(as2 < 1) as2 = 1.0/as2;
00532       
00533       if( //both blobs must be semi-circular, prefer those that are wider
00534           ratios[i] > 0.75 &&   ratios[i] < 2 &&
00535           ratios[i+1] > 0.75 && ratios[i+1] < 2 &&
00536           //both blobs must be similar in shape
00537           QMAX(as2,as1)/QMIN(as2,as1) < 2 &&
00538           //both blobs must be similar in size
00539           ((double)QMAX( sizes[i], sizes[i+1] )) / QMIN( sizes[i], sizes[i+1] ) < 1.5 &&
00540           //both blobs must be above a certain thresh size, this prevents selecting blobs that are very very tiny
00541           //if only tiny blobs are around we'll end up desaturating entire region
00542           QMAX( sizes[i], sizes[i+1] ) > 20 )
00543       {
00544         id1 = ids[i];
00545         id2 = ids[i+1];
00546         break;
00547       }    
00548     }
00549   }
00550   
00551   //Comment this sectionin to see what blobs were found and selected
00552 /* cout << "-----\n";
00553   for(i=0; i<blobCount-1; i++)
00554   {
00555     if( ids[i] == id1 || ids[i] == id2 )
00556       cout << "--->";
00557     cout << "ID: " << ids[i] << "count: " << sizes[i] << " w:h: " << ratios[i] << "\n";      
00558   }*/
00559 }

void findBlobs (  ) 

Definition at line 372 of file redEye.cpp.

References blobAspectRatios, blobBottomRight, blobIDs, blobPixelCount, blobSizes, blobTopLeft, bottomRight, MIN_RED_VAL, pushPixel(), rawImage, regionHeight, regionOfInterest, regionWidth, spreadablePixels, and topLeft.

Referenced by removeRedeyeRegions().

00373 {
00374   //create small matrix for region of interest
00375   regionWidth = bottomRight.x() - topLeft.x() + 1;
00376   regionHeight = bottomRight.y() - topLeft.y() + 1;  
00377   regionOfInterest = new int[ regionWidth * regionHeight ];
00378   
00379   //set all pixels that meet thresh to 1, all others to 0
00380   int x, y;
00381   int x2, y2;
00382   QRgb* rgb;
00383   uchar* scanLine;
00384   for( y=topLeft.y(); y<=bottomRight.y(); y++)
00385   {
00386     y2 = y - topLeft.y();
00387     
00388     scanLine = rawImage.scanLine(y);
00389     for( x=topLeft.x(); x<=bottomRight.x(); x++)
00390     {
00391     
00392       x2 = x - topLeft.x();
00393       
00394       rgb = ((QRgb*)scanLine+x);
00395       
00396       bool threshMet = qRed(*rgb) > 2*qGreen(*rgb) &&
00397                        qRed(*rgb) > MIN_RED_VAL;
00398       
00399       if(threshMet)
00400         regionOfInterest[ x2 + y2*regionWidth ] = 1;
00401       else
00402         regionOfInterest[ x2 + y2*regionWidth ] = 0;
00403     }
00404   } 
00405   
00406   //walk over region of interest and propogate blobs
00407   int nextValidID = 2;
00408   for(x = 0; x<regionWidth; x++)
00409   {
00410     for(y = 0; y<regionHeight; y++)
00411     {
00412       //if any blobs can be propogated handle them first
00413       while( !spreadablePixels.empty() )
00414       {
00415         QPoint point = spreadablePixels.pop();
00416         int id = regionOfInterest[ point.x() + point.y()*regionWidth ];
00417         
00418         pushPixel( point.x()-1, point.y()-1, id );
00419         pushPixel( point.x(),   point.y()-1, id );
00420         pushPixel( point.x()+1, point.y()-1, id );
00421         pushPixel( point.x()-1, point.y(), id );
00422         pushPixel( point.x()+1, point.y(), id );
00423         pushPixel( point.x()-1, point.y()+1, id );
00424         pushPixel( point.x(),   point.y()+1, id );
00425         pushPixel( point.x()+1, point.y()+1, id );
00426       }
00427       
00428       //if this pixel has met thresh and has not yet been assigned a unique ID,
00429       //assign it the next unique id and push all valid neighbors
00430       if( regionOfInterest[ x + y*regionWidth ] == 1 )
00431       {
00432         //print last blob stats
00433         if( nextValidID > 2)
00434         {
00435           blobIDs.push( (nextValidID - 1) );
00436           blobSizes.push( blobPixelCount );
00437           blobAspectRatios.push( ((double)(blobBottomRight.x() - blobTopLeft.x()+1)) / 
00438                                           (blobBottomRight.y() - blobTopLeft.y()+1) );
00439         }
00440         
00441         regionOfInterest[x + y*regionWidth] = nextValidID;
00442         pushPixel( x-1, y-1, nextValidID );
00443         pushPixel( x,   y-1, nextValidID );
00444         pushPixel( x+1, y-1, nextValidID );
00445         pushPixel( x-1, y, nextValidID );
00446         pushPixel( x+1, y, nextValidID );
00447         pushPixel( x-1, y+1, nextValidID );
00448         pushPixel( x,   y+1, nextValidID );
00449         pushPixel( x+1, y+1, nextValidID );
00450         nextValidID++;        
00451         
00452         blobPixelCount = 1;
00453         blobTopLeft = QPoint( x, y );
00454         blobBottomRight = QPoint( x, y );
00455       }
00456     } //y
00457   } //x
00458   
00459   //insert last blob stats
00460   if( nextValidID > 2)
00461   {
00462     blobIDs.push( (nextValidID - 1) );
00463     blobSizes.push( blobPixelCount );
00464     blobAspectRatios.push( ((double)(blobBottomRight.x() - blobTopLeft.x()+1)) / (blobBottomRight.y() - blobTopLeft.y()+1) );
00465   }
00466 }

void findRegionOfInterest ( QPoint  topLeftExtreme,
QPoint  bottomRightExtreme 
)

Definition at line 305 of file redEye.cpp.

References bottomRight, StatusWidget::incrementProgress(), MIN_RED_VAL, newProgress, rawImage, status, topLeft, and updateIncrement.

Referenced by removeRedeyeRegions().

00306 {
00307   topLeft = QPoint(-1,-1);
00308   bottomRight = QPoint(-1,-1);
00309   
00310   int x, y;
00311   QRgb* rgb;
00312   uchar* scanLine;
00313   for( y=topLeftExtreme.y(); y<=bottomRightExtreme.y(); y++)
00314   {
00315     scanLine = rawImage.scanLine(y);
00316     for( x=topLeftExtreme.x(); x<=bottomRightExtreme.x(); x++)
00317     {
00318       rgb = ((QRgb*)scanLine+x);
00319       
00320       bool threshMet = qRed(*rgb) > 2*qGreen(*rgb) &&
00321                       qRed(*rgb) > MIN_RED_VAL;
00322       if(threshMet)
00323       {
00324         //first pixel
00325         if(topLeft.x() == -1) 
00326         {
00327           topLeft = QPoint(x,y);
00328           bottomRight = QPoint(x,y);
00329         }
00330         
00331         if(x < topLeft.x() ) topLeft.setX( x );
00332         if(y < topLeft.y() ) topLeft.setY( y );
00333         if(x > bottomRight.x() ) bottomRight.setX( x );
00334         if(y > bottomRight.y() ) bottomRight.setY( y );
00335       }
00336       
00337       //update status bar if significant progress has been made since last update
00338       newProgress++;
00339       if(newProgress >= updateIncrement)
00340       {
00341         newProgress = 0;
00342         status->incrementProgress();
00343         qApp->processEvents();  
00344       }
00345       
00346     }
00347   }  
00348 }

bool IDedPixel ( int  x,
int  y 
)

Definition at line 561 of file redEye.cpp.

References bottomRight, id1, id2, regionIndex(), regionOfInterest, regionWidth, and topLeft.

Referenced by desaturateAlpha().

00562 {
00563   if( x < topLeft.x() || y < topLeft.y() ||
00564       x > bottomRight.x() || y > bottomRight.y() )
00565     return false;
00566   
00567   int regionIndex = x - topLeft.x() + (y-topLeft.y())*regionWidth;
00568   return ( regionOfInterest[regionIndex] == id1 ||
00569            regionOfInterest[regionIndex] == id2 );
00570 }

void pushPixel ( int  x,
int  y,
int  id 
)

Definition at line 350 of file redEye.cpp.

References blobBottomRight, blobPixelCount, blobTopLeft, regionHeight, regionOfInterest, regionWidth, and spreadablePixels.

Referenced by findBlobs().

00351 {
00352   //if pixel off image or below thresh ignore push attempt
00353   if(  x < 0  || 
00354        y <  0 ||
00355        x >= regionWidth ||
00356        y >= regionHeight ||
00357        regionOfInterest[ x + y*regionWidth ] != 1 )
00358     return;
00359   
00360   //passes! set id and actually put pixel onto stack
00361   regionOfInterest[ x + y*regionWidth] = id;  
00362   spreadablePixels.push( QPoint( x, y ) );
00363   
00364   //increase blob pixel count and update topLeft and bottomRight
00365   blobPixelCount++;
00366   blobTopLeft.setX( QMIN( x, blobTopLeft.x() ) );
00367   blobTopLeft.setY( QMIN( y, blobTopLeft.y() ) );
00368   blobBottomRight.setX( QMAX( x, blobBottomRight.x() ) );
00369   blobBottomRight.setY( QMAX( y, blobBottomRight.y() ) );
00370 }

void sortBlobsByDecreasingSize (  ) 

Definition at line 468 of file redEye.cpp.

References blobAspectRatios, blobCount, blobIDs, blobSizes, ids, ratios, and sizes.

Referenced by removeRedeyeRegions().

00469 {
00470   blobCount = blobIDs.count();
00471   ids = new int[blobCount];
00472   sizes = new int[blobCount];
00473   ratios = new double[blobCount];
00474   
00475   int i,j;
00476   for(i=0; i<blobCount; i++)
00477   {
00478     ids[i] = blobIDs.pop();
00479     sizes[i] = blobSizes.pop();
00480     ratios[i] = blobAspectRatios.pop();
00481   }
00482   
00483   //quick and dirty bubble sort
00484   for(j = blobCount-1; j>0; j--)
00485   {
00486     for(i=0; i<j; i++)
00487     {
00488       if( sizes[i+1] > sizes[i] )
00489       {
00490         int t = sizes[i+1];
00491         sizes[i+1] = sizes[i];
00492         sizes[i] = t;
00493         
00494         t = ids[i+1];
00495         ids[i+1] = ids[i];
00496         ids[i] = t;
00497         
00498         double tR = ratios[i+1];
00499         ratios[i+1] = ratios[i];
00500         ratios[i] = tR;        
00501       }
00502     }
00503   }
00504 }


Variable Documentation

QValueStack<double> blobAspectRatios

Definition at line 58 of file redEye_internal.h.

Referenced by findBlobs(), and sortBlobsByDecreasingSize().

QPoint blobBottomRight

Definition at line 50 of file redEye_internal.h.

Referenced by findBlobs(), and pushPixel().

int blobCount

Definition at line 63 of file redEye_internal.h.

Referenced by findBestTwoBlobs(), and sortBlobsByDecreasingSize().

QValueStack<int> blobIDs

Definition at line 56 of file redEye_internal.h.

Referenced by findBlobs(), and sortBlobsByDecreasingSize().

int blobPixelCount

Definition at line 49 of file redEye_internal.h.

Referenced by findBlobs(), and pushPixel().

QValueStack<int> blobSizes

Definition at line 57 of file redEye_internal.h.

Referenced by findBlobs(), and sortBlobsByDecreasingSize().

QPoint blobTopLeft

Definition at line 50 of file redEye_internal.h.

Referenced by findBlobs(), and pushPixel().

QPoint bottomRight

Definition at line 42 of file redEye_internal.h.

Referenced by correctImageTilt(), EditingInterface::crop(), desaturateBlobs(), findBlobs(), findRegionOfInterest(), EditingInterface::handleSelectionChanged(), IDedPixel(), SelectionInterface::keyPressEvent(), SelectionInterface::mouseActionByPosition(), SelectionInterface::mouseMoveEvent(), SelectionInterface::mousePressEvent(), SelectionInterface::mouseReleaseEvent(), SelectionPlacementInterface::paintEvent(), SelectionInterface::paintEvent(), EditingInterface::removeRedeye(), EditingInterface::rotateSelection(), and SelectionInterface::scaleSelection().

QImage* editedImage

Definition at line 37 of file redEye_internal.h.

Referenced by EditingInterface::applyEffect(), blackWhiteEffect(), correctImageTilt(), desaturateBlobs(), desaturateEntireImage(), embossEffect(), enhanceImageContrast(), improveColorBalance(), invertEffect(), mosaicEffect(), oilPaintingEffect(), pointillismEffect(), removeRedeyeRegions(), EditingInterface::selectEffect(), and sepiaEffect().

int id1

Definition at line 71 of file redEye_internal.h.

Referenced by findBestTwoBlobs(), IDedPixel(), and removeRedeyeRegions().

int id2

Definition at line 71 of file redEye_internal.h.

Referenced by findBestTwoBlobs(), and IDedPixel().

int* ids

Definition at line 64 of file redEye_internal.h.

Referenced by findBestTwoBlobs(), and sortBlobsByDecreasingSize().

int newProgress

Definition at line 31 of file redEye_internal.h.

Referenced by blackWhiteEffect(), correctImageTilt(), embossEffect(), enhanceImageContrast(), findRegionOfInterest(), improveColorBalance(), mosaicEffect(), oilPaintingEffect(), removeRedeyeRegions(), and sepiaEffect().

double* ratios

Definition at line 66 of file redEye_internal.h.

Referenced by findBestTwoBlobs(), and sortBlobsByDecreasingSize().

QImage rawImage

Definition at line 34 of file redEye_internal.h.

Referenced by findBlobs(), findRegionOfInterest(), and removeRedeyeRegions().

int regionHeight

Definition at line 47 of file redEye_internal.h.

Referenced by findBlobs(), and pushPixel().

int* regionOfInterest

Definition at line 52 of file redEye_internal.h.

Referenced by findBlobs(), IDedPixel(), and pushPixel().

int regionWidth

Definition at line 47 of file redEye_internal.h.

Referenced by findBlobs(), IDedPixel(), and pushPixel().

int* sizes

Definition at line 65 of file redEye_internal.h.

Referenced by findBestTwoBlobs(), and sortBlobsByDecreasingSize().

QValueStack<QPoint> spreadablePixels

Definition at line 54 of file redEye_internal.h.

Referenced by findBlobs(), and pushPixel().

StatusWidget* status

Definition at line 21 of file redEye_internal.h.

Referenced by blackWhiteEffect(), embossEffect(), findRegionOfInterest(), oilPaintingEffect(), removeRedeyeRegions(), and sepiaEffect().

QPoint topLeft

Definition at line 42 of file redEye_internal.h.

Referenced by PhotosIconView::captureClick(), correctImageTilt(), EditingInterface::crop(), desaturateBlobs(), findBlobs(), findRegionOfInterest(), EditingInterface::handleSelectionChanged(), IDedPixel(), SelectionInterface::keyPressEvent(), SelectionInterface::mouseActionByPosition(), SelectionInterface::mouseMoveEvent(), SelectionInterface::mousePressEvent(), SelectionInterface::mouseReleaseEvent(), SelectionPlacementInterface::paintEvent(), SelectionInterface::paintEvent(), EditingInterface::removeRedeye(), removeRedeyeRegions(), EditingInterface::rotateSelection(), SelectionInterface::scaleSelection(), and Item::setTextWidth().

int updateIncrement

Definition at line 28 of file redEye_internal.h.

Referenced by blackWhiteEffect(), correctImageTilt(), embossEffect(), enhanceImageContrast(), findRegionOfInterest(), improveColorBalance(), mosaicEffect(), oilPaintingEffect(), removeRedeyeRegions(), and sepiaEffect().


Generated on Thu Jan 3 10:52:48 2008 for AlbumShaper by  doxygen 1.5.4