|
AlbumShaper
1.0a3
|
#include <qimage.h>#include <qvaluestack.h>#include <qpoint.h>

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 | |
| StatusWidget * | status |
| 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 |
| double desaturateAlpha | ( | int | x, |
| int | y | ||
| ) |
Definition at line 572 of file redEye.cpp.
References IDedPixel().
Referenced by desaturateBlobs().
{
int n = 0;
if( IDedPixel(x ,y ) ) n++;
if(n == 1)
return 1.0;
if( IDedPixel(x-1,y-1) ) n++;
if( IDedPixel(x ,y-1) ) n++;
if( IDedPixel(x+1,y-1) ) n++;
if( IDedPixel(x-1,y ) ) n++;
if( IDedPixel(x+1,y ) ) n++;
if( IDedPixel(x-1,y+1) ) n++;
if( IDedPixel(x ,y+1) ) n++;
if( IDedPixel(x+1,y+1) ) n++;
if( IDedPixel(x-2,y-2) ) n++;
if( IDedPixel(x-1,y-2) ) n++;
if( IDedPixel(x ,y-2) ) n++;
if( IDedPixel(x+1,y-2) ) n++;
if( IDedPixel(x+2,y-2) ) n++;
if( IDedPixel(x-2,y-1) ) n++;
if( IDedPixel(x+2,y-1) ) n++;
if( IDedPixel(x-2,y ) ) n++;
if( IDedPixel(x+2,y ) ) n++;
if( IDedPixel(x-2,y+1) ) n++;
if( IDedPixel(x+2,y+1) ) n++;
if( IDedPixel(x-2,y+2) ) n++;
if( IDedPixel(x-1,y+2) ) n++;
if( IDedPixel(x ,y+2) ) n++;
if( IDedPixel(x+1,y+2) ) n++;
if( IDedPixel(x+2,y+2) ) n++;
return ((double)n) / 25;
}
| void desaturateBlobs | ( | ) |
Definition at line 612 of file redEye.cpp.
References bottomRight, desaturateAlpha(), editedImage, and topLeft.
Referenced by removeRedeyeRegions().
{
//desaturate bad pixels
int x, y;
double r;
QRgb* rgb;
uchar* scanLine;
for( y = QMAX( topLeft.y()-1, 0);
y<= QMIN( bottomRight.y()+1, editedImage->height()-1 );
y++)
{
scanLine = editedImage->scanLine(y);
for( x = QMAX( topLeft.x()-1, 0);
x <= QMIN( bottomRight.x()+1, editedImage->width()-1 );
x++)
{
double alpha = desaturateAlpha( x, y );
if( alpha > 0)
{
rgb = ((QRgb*)scanLine+x);
r = alpha*(0.05*qRed(*rgb) + 0.6*qGreen(*rgb) + 0.3*qBlue(*rgb)) +
(1-alpha)*qRed(*rgb);
*rgb = qRgb( (int)r,
qGreen(*rgb),
qBlue(*rgb) );
} //alpha > 0
} //x
} //y
}
| void desaturateEntireImage | ( | QPoint | topLeftExtreme, |
| QPoint | bottomRightExtreme | ||
| ) |
Definition at line 643 of file redEye.cpp.
References editedImage.
Referenced by removeRedeyeRegions().
{
//desaturate bad pixels
int x, y;
QRgb* rgb;
uchar* scanLine;
for( y=topLeftExtreme.y(); y<=bottomRightExtreme.y(); y++)
{
scanLine = editedImage->scanLine(y);
for( x=topLeftExtreme.x(); x<=bottomRightExtreme.x(); x++)
{
rgb = ((QRgb*)scanLine+x);
if( qRed(*rgb) > 2*qGreen(*rgb) )
{
*rgb = qRgb( (int) (0.05*qRed(*rgb) + 0.6*qGreen(*rgb) + 0.3*qBlue(*rgb)),
qGreen(*rgb),
qBlue(*rgb) );
} // > thresh
} //x
} //y
}
| void findBestTwoBlobs | ( | ) |
Definition at line 506 of file redEye.cpp.
References blobCount, id1, id2, ids, ratios, and sizes.
Referenced by removeRedeyeRegions().
{
id1 = -1;
id2 = -1;
int i;
//special case: 2 blobs found, both larger than 1 pixel
if(blobCount == 2 &&
sizes[0] > 1 &&
sizes[1] > 1)
{
id1 = ids[0];
id2 = ids[1];
}
else
{
for(i=0; i<blobCount-2; i++)
{
//once we hit blobs that are only one pixel large stop because they are probably just noise
if( sizes[i+1] <= 1 ) break;
double as1 = ratios[i];
double as2 = ratios[i+1];
if(as1 < 1) as1 = 1.0/as1;
if(as2 < 1) as2 = 1.0/as2;
if( //both blobs must be semi-circular, prefer those that are wider
ratios[i] > 0.75 && ratios[i] < 2 &&
ratios[i+1] > 0.75 && ratios[i+1] < 2 &&
//both blobs must be similar in shape
QMAX(as2,as1)/QMIN(as2,as1) < 2 &&
//both blobs must be similar in size
((double)QMAX( sizes[i], sizes[i+1] )) / QMIN( sizes[i], sizes[i+1] ) < 1.5 &&
//both blobs must be above a certain thresh size, this prevents selecting blobs that are very very tiny
//if only tiny blobs are around we'll end up desaturating entire region
QMAX( sizes[i], sizes[i+1] ) > 20 )
{
id1 = ids[i];
id2 = ids[i+1];
break;
}
}
}
//Comment this sectionin to see what blobs were found and selected
/* cout << "-----\n";
for(i=0; i<blobCount-1; i++)
{
if( ids[i] == id1 || ids[i] == id2 )
cout << "--->";
cout << "ID: " << ids[i] << "count: " << sizes[i] << " w:h: " << ratios[i] << "\n";
}*/
}
| 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().
{
//create small matrix for region of interest
regionWidth = bottomRight.x() - topLeft.x() + 1;
regionHeight = bottomRight.y() - topLeft.y() + 1;
regionOfInterest = new int[ regionWidth * regionHeight ];
//set all pixels that meet thresh to 1, all others to 0
int x, y;
int x2, y2;
QRgb* rgb;
uchar* scanLine;
for( y=topLeft.y(); y<=bottomRight.y(); y++)
{
y2 = y - topLeft.y();
scanLine = rawImage.scanLine(y);
for( x=topLeft.x(); x<=bottomRight.x(); x++)
{
x2 = x - topLeft.x();
rgb = ((QRgb*)scanLine+x);
bool threshMet = qRed(*rgb) > 2*qGreen(*rgb) &&
qRed(*rgb) > MIN_RED_VAL;
if(threshMet)
regionOfInterest[ x2 + y2*regionWidth ] = 1;
else
regionOfInterest[ x2 + y2*regionWidth ] = 0;
}
}
//walk over region of interest and propogate blobs
int nextValidID = 2;
for(x = 0; x<regionWidth; x++)
{
for(y = 0; y<regionHeight; y++)
{
//if any blobs can be propogated handle them first
while( !spreadablePixels.empty() )
{
QPoint point = spreadablePixels.pop();
int id = regionOfInterest[ point.x() + point.y()*regionWidth ];
pushPixel( point.x()-1, point.y()-1, id );
pushPixel( point.x(), point.y()-1, id );
pushPixel( point.x()+1, point.y()-1, id );
pushPixel( point.x()-1, point.y(), id );
pushPixel( point.x()+1, point.y(), id );
pushPixel( point.x()-1, point.y()+1, id );
pushPixel( point.x(), point.y()+1, id );
pushPixel( point.x()+1, point.y()+1, id );
}
//if this pixel has met thresh and has not yet been assigned a unique ID,
//assign it the next unique id and push all valid neighbors
if( regionOfInterest[ x + y*regionWidth ] == 1 )
{
//print last blob stats
if( nextValidID > 2)
{
blobIDs.push( (nextValidID - 1) );
blobSizes.push( blobPixelCount );
blobAspectRatios.push( ((double)(blobBottomRight.x() - blobTopLeft.x()+1)) /
(blobBottomRight.y() - blobTopLeft.y()+1) );
}
regionOfInterest[x + y*regionWidth] = nextValidID;
pushPixel( x-1, y-1, nextValidID );
pushPixel( x, y-1, nextValidID );
pushPixel( x+1, y-1, nextValidID );
pushPixel( x-1, y, nextValidID );
pushPixel( x+1, y, nextValidID );
pushPixel( x-1, y+1, nextValidID );
pushPixel( x, y+1, nextValidID );
pushPixel( x+1, y+1, nextValidID );
nextValidID++;
blobPixelCount = 1;
blobTopLeft = QPoint( x, y );
blobBottomRight = QPoint( x, y );
}
} //y
} //x
//insert last blob stats
if( nextValidID > 2)
{
blobIDs.push( (nextValidID - 1) );
blobSizes.push( blobPixelCount );
blobAspectRatios.push( ((double)(blobBottomRight.x() - blobTopLeft.x()+1)) / (blobBottomRight.y() - blobTopLeft.y()+1) );
}
}
| 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().
{
topLeft = QPoint(-1,-1);
bottomRight = QPoint(-1,-1);
int x, y;
QRgb* rgb;
uchar* scanLine;
for( y=topLeftExtreme.y(); y<=bottomRightExtreme.y(); y++)
{
scanLine = rawImage.scanLine(y);
for( x=topLeftExtreme.x(); x<=bottomRightExtreme.x(); x++)
{
rgb = ((QRgb*)scanLine+x);
bool threshMet = qRed(*rgb) > 2*qGreen(*rgb) &&
qRed(*rgb) > MIN_RED_VAL;
if(threshMet)
{
//first pixel
if(topLeft.x() == -1)
{
topLeft = QPoint(x,y);
bottomRight = QPoint(x,y);
}
if(x < topLeft.x() ) topLeft.setX( x );
if(y < topLeft.y() ) topLeft.setY( y );
if(x > bottomRight.x() ) bottomRight.setX( x );
if(y > bottomRight.y() ) bottomRight.setY( y );
}
//update status bar if significant progress has been made since last update
newProgress++;
if(newProgress >= updateIncrement)
{
newProgress = 0;
status->incrementProgress();
qApp->processEvents();
}
}
}
}
| 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().
{
if( x < topLeft.x() || y < topLeft.y() ||
x > bottomRight.x() || y > bottomRight.y() )
return false;
int regionIndex = x - topLeft.x() + (y-topLeft.y())*regionWidth;
return ( regionOfInterest[regionIndex] == id1 ||
regionOfInterest[regionIndex] == id2 );
}
| 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().
{
//if pixel off image or below thresh ignore push attempt
if( x < 0 ||
y < 0 ||
x >= regionWidth ||
y >= regionHeight ||
regionOfInterest[ x + y*regionWidth ] != 1 )
return;
//passes! set id and actually put pixel onto stack
regionOfInterest[ x + y*regionWidth] = id;
spreadablePixels.push( QPoint( x, y ) );
//increase blob pixel count and update topLeft and bottomRight
blobPixelCount++;
blobTopLeft.setX( QMIN( x, blobTopLeft.x() ) );
blobTopLeft.setY( QMIN( y, blobTopLeft.y() ) );
blobBottomRight.setX( QMAX( x, blobBottomRight.x() ) );
blobBottomRight.setY( QMAX( y, blobBottomRight.y() ) );
}
| void sortBlobsByDecreasingSize | ( | ) |
Definition at line 468 of file redEye.cpp.
References blobAspectRatios, blobCount, blobIDs, blobSizes, ids, ratios, and sizes.
Referenced by removeRedeyeRegions().
{
blobCount = blobIDs.count();
ids = new int[blobCount];
sizes = new int[blobCount];
ratios = new double[blobCount];
int i,j;
for(i=0; i<blobCount; i++)
{
ids[i] = blobIDs.pop();
sizes[i] = blobSizes.pop();
ratios[i] = blobAspectRatios.pop();
}
//quick and dirty bubble sort
for(j = blobCount-1; j>0; j--)
{
for(i=0; i<j; i++)
{
if( sizes[i+1] > sizes[i] )
{
int t = sizes[i+1];
sizes[i+1] = sizes[i];
sizes[i] = t;
t = ids[i+1];
ids[i+1] = ids[i];
ids[i] = t;
double tR = ratios[i+1];
ratios[i+1] = ratios[i];
ratios[i] = tR;
}
}
}
}
| 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(), SelectionInterface::scaleSelection(), and SelectionInterface::setSelection().
| QImage* editedImage |
Definition at line 37 of file redEye_internal.h.
Referenced by EditingInterface::applyEffect(), EditingInterface::applyImageUpdate(), 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().
Definition at line 21 of file redEye_internal.h.
Referenced by blackWhiteEffect(), embossEffect(), findRegionOfInterest(), mosaicEffect(), 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(), SelectionInterface::setSelection(), 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().
1.7.5.1