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().