AlbumShaper
1.0a3
|
#include <edgeDetect.h>
Public Member Functions | |
EdgeDetect (QImage *image) | |
~EdgeDetect () | |
int | getNumClusters () |
PixelCluster * | getClusters () |
int * | getSmoothHist () |
int * | getPeaks () |
QImage * | getEdgeImage () |
int * | getClusterMap () |
Private Member Functions | |
void | allocateAndInitObjects () |
void | constructGSLClut () |
void | fillLumMapAndLumHistogram () |
void | smoothLumHistogram () |
void | computeEdgeMagAndGSLCmaps () |
int | pixelLum (int x, int y) |
void | findPixelClusters () |
void | computeClusterStatistics () |
void | computeClusterThresholds () |
void | constructEdgeImage () |
void | deallocateObjects () |
Private Attributes | |
LUTentry | LUT [256] |
QImage * | image |
int | lumHist [256] |
luminosity and smooth luminosity histograms | |
int | smoothLumHist [256] |
int | clusterPeaks [256] |
int * | lumMap |
float * | edgeMagMap |
int * | GSLCmap |
int | numClusters |
PixelCluster * | clusters |
int | minClusterSize |
int | maxClusterSize |
Definition at line 45 of file edgeDetect.h.
EdgeDetect::EdgeDetect | ( | QImage * | image | ) |
Definition at line 192 of file edgeDetect.cpp.
References allocateAndInitObjects(), computeClusterStatistics(), computeClusterThresholds(), computeEdgeMagAndGSLCmaps(), constructEdgeImage(), fillLumMapAndLumHistogram(), findPixelClusters(), image, and smoothLumHistogram().
{ //load image this->image = image; //allocate and initialize objects used for edge detection allocateAndInitObjects(); //fill lum map and lum histogram fillLumMapAndLumHistogram(); //fill smoothed histogram smoothLumHistogram(); //compute edge magnitude and GSLC maps computeEdgeMagAndGSLCmaps(); //determine pixel clusters findPixelClusters(); computeClusterStatistics(); computeClusterThresholds(); constructEdgeImage(); }
EdgeDetect::~EdgeDetect | ( | ) |
Definition at line 219 of file edgeDetect.cpp.
References deallocateObjects().
{ deallocateObjects(); }
void EdgeDetect::allocateAndInitObjects | ( | ) | [private] |
Definition at line 264 of file edgeDetect.cpp.
References clusterPeaks, constructGSLClut(), edgeMagMap, GSLCmap, image, lumHist, lumMap, and smoothLumHist.
Referenced by EdgeDetect().
{ //initialize: //-luminosity histogram //-smoothed luminosity histogram //-identified peak regions int i; for(i=0; i<256; i++) { lumHist[i] = 0; smoothLumHist[i] = 0; clusterPeaks[i] = 0; } //allocate luminance map lumMap = new int[image->width() * image->height()]; //allocate edge magnitude map edgeMagMap = new float[image->width() * image->height()]; //allocate GSLC map GSLCmap = new int[image->width() * image->height()]; //construct LUT constructGSLClut(); }
void EdgeDetect::computeClusterStatistics | ( | ) | [private] |
Definition at line 546 of file edgeDetect.cpp.
References clusterPeaks, clusters, PixelCluster::edgeMagHistogram, edgeMagMap, image, lumMap, maxClusterSize, PixelCluster::meanMode, minClusterSize, PixelCluster::mode, numClusters, PixelCluster::numPixels, PixelCluster::pixelCount, and PixelCluster::totalEdgeMagnitude.
Referenced by EdgeDetect().
{ //initialize cluster stats int cluster; for(cluster=0; cluster<numClusters; cluster++) { int i; for(i=0; i<256; i++) { clusters[cluster].edgeMagHistogram[i] = 0; } clusters[cluster].totalEdgeMagnitude=0.0f; clusters[cluster].numPixels = 0; } //iterate over all pixels int i; for(i=0; i<image->width()*image->height(); i++) { //skip pixels that don't belong to peaks if( clusterPeaks[ lumMap[i] ] != 1) continue; //determine cluster pixel belongs to int cluster; for(cluster=0; cluster<numClusters; cluster++) { if( lumMap[i] >= clusters[cluster].minLuminance && lumMap[i] <= clusters[cluster].maxLuminance ) { clusters[cluster].totalEdgeMagnitude+= edgeMagMap[i]; clusters[cluster].numPixels++; clusters[cluster].edgeMagHistogram[ QMIN( QMAX( (int)edgeMagMap[i], 0), 255) ]++; break; } } //cluster } //pixel i //iterate over clusters to determine min and max peak cluster sizes minClusterSize = clusters[0].numPixels; maxClusterSize = clusters[0].numPixels; for(cluster=1; cluster<numClusters; cluster++) { if(clusters[cluster].numPixels < minClusterSize) minClusterSize = clusters[cluster].numPixels; if(clusters[cluster].numPixels > maxClusterSize) maxClusterSize = clusters[cluster].numPixels; } //iterate over clusters one final time to deduce normalized inputs to fuzzy logic process int JND = 255/50; for(cluster=0; cluster<numClusters; cluster++) { clusters[cluster].meanMode = QMIN( clusters[cluster].totalEdgeMagnitude / clusters[cluster].numPixels, 3*JND ); int i; int mode = 0; for(i=1; i<256; i++) { if( clusters[cluster].edgeMagHistogram[i] > clusters[cluster].edgeMagHistogram[ mode ] ) mode = i; } clusters[cluster].mode = QMIN( mode, 2*JND ); clusters[cluster].pixelCount = ((float)(clusters[cluster].numPixels - minClusterSize)) / (maxClusterSize - minClusterSize); } }
void EdgeDetect::computeClusterThresholds | ( | ) | [private] |
Definition at line 618 of file edgeDetect.cpp.
References B, b, PixelCluster::beta, clusters, PixelCluster::edgeThreshold, PixelCluster::mode, and numClusters.
Referenced by EdgeDetect().
{ //iterate over each cluster int cluster; float S1,M1,L1; float S2,M2,L2; float S3,L3; float outS, outM, outL; int JND = 255/50; for(cluster=0; cluster<numClusters; cluster++) { //---- //compute S,M, and L values for each input //---- S1 = QMAX( 1.0f - ((clusters[cluster].meanMode/JND) / 1.5f), 0 ); if( (clusters[cluster].meanMode/JND) <= 1.5f ) M1 = QMAX( (clusters[cluster].meanMode/JND) - 0.5f, 0 ); else M1 = QMAX( 2.5f - (clusters[cluster].meanMode/JND), 0 ); L1 = QMAX( ((clusters[cluster].meanMode/JND) - 1.5f) / 1.5f, 0 ); //---- S2 = QMAX( 1.0f - (clusters[cluster].mode/JND), 0 ); if( (clusters[cluster].mode/JND) <= 1.0f ) M2 = QMAX( -1.0f + 2*(clusters[cluster].mode/JND), 0 ); else M2 = QMAX( 3.0f - 2*(clusters[cluster].mode/JND), 0 ); L2 = QMAX( (clusters[cluster].mode/JND) - 1.0, 0 ); //---- S3 = QMAX( 1.0f - 2*clusters[cluster].pixelCount, 0 ); L3 = QMAX( -1.0f + 2*clusters[cluster].pixelCount, 0 ); //---- //Compute M,L for outputs using set of 18 rules. //outS is inherantly S given the ruleset provided outS = 0.0f; outM = 0.0f; outL = 0.0f; //Out 1 if( numClusters > 2 ) { outM += S1*S2*S3; //rule 1 //rule 2 if( clusters[cluster].meanMode < clusters[cluster].mode ) outS += S1*S2*L3; else outM += S1*S2*L3; outM += S1*M2*S3; //rule 3 outM += S1*M2*L3; //rule 4 outM += S1*L2*S3; //rule 5 outM += S1*L2*L3; //rule 6 outM += M1*S2*S3; //rule 7 outM += M1*S2*L3; //rule 8 outM += M1*M2*S3; //rule 9 outL += M1*M2*L3; //rule 10 outM += M1*L2*S3; //rule 11 outL += M1*L2*L3; //rule 12 outM += L1*S2*S3; //rule 13 outL += L1*S2*L3; //rule 14 outM += L1*M2*S3; //rule 15 outL += L1*M2*L3; //rule 16 outL += L1*L2*S3; //rule 17 outL += L1*L2*L3; //rule 18 } //Out 2 else { outL += S1*S2*S3; //rule 1 outL += S1*S2*L3; //rule 2 outM += S1*M2*S3; //rule 3 outL += S1*M2*L3; //rule 4 outM += S1*L2*S3; //rule 5 outM += S1*L2*L3; //rule 6 outL += M1*S2*S3; //rule 7 outL += M1*S2*L3; //rule 8 outL += M1*M2*S3; //rule 9 outL += M1*M2*L3; //rule 10 outL += M1*L2*S3; //rule 11 outL += M1*L2*L3; //rule 12 outL += L1*S2*S3; //rule 13 outL += L1*S2*L3; //rule 14 outL += L1*M2*S3; //rule 15 outL += L1*M2*L3; //rule 16 outL += L1*L2*S3; //rule 17 outL += L1*L2*L3; //rule 18 } //find centroid - Beta[k] float A = outM + 0.5f; float B = 2.5f - outM; float C = 1.5f * (outL + 1); float D = 1.5f * (outM + 1); float E = 2.5f - outL; //--------------------------------------------------------------- //Case 1: Both outM and outL are above intersection point of diagonals if( outM > 0.5f && outL > 0.5f ) { //find area of 7 subregions float area1 = ((A-0.5f)*outM)/2; float area2 = outM * (B-A); float area3 = ((2.1f-B) * (outM - 0.5)) / 2; float area4 = (2.1 - B) * 0.5f; float area5 = ((C - 2.1f) * (outL - 0.5)) / 2; float area6 = (C - 2.1f) * 0.5f; float area7 = (3.0f - C) * outL; //find half of total area float halfArea = (area1 + area2 + area3 + area4 + area5 + area6 + area7) / 2; //determine which region split will be within and resulting horizontal midpoint //Within area 1 if( area1 > halfArea ) { clusters[cluster].beta = 0.5f + (float)sqrt(2*halfArea); } //Within area 2 else if( area1 + area2 > halfArea ) { clusters[cluster].beta = ((halfArea - area1) / outM) + A; } //Within area 3-4 else if( area1 + area2 + area3 + area4 > halfArea ) { float a = -0.5f; float b = 2.8f; float c = area1 + area2 + area3 - halfArea - B/2 - 2.625f; clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); } //Within area 5-6 else if( area1 + area2 + area3 + area4 + area5 + area6 > halfArea ) { float a = 1.0f/3; float b = -0.7f; float c = area1 + area2 + area3 + area4 - halfArea; clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); } //Within area 7 else { clusters[cluster].beta = ((halfArea - (area1 + area2 + area3 + area4 + area5 + area6) ) / outL) + C; } } //end case 1 //--------------------------------------------------------------- //Case 2 else if ( outM < 0.5f && outL > outM ) { //find area of 5 subregions float area1 = (outM*(A-0.5f)) / 2; float area2 = (D-A) * outM; float area3 = ((C-D) * (outL - outM)) / 2; float area4 = (C-D) * outM; float area5 = (3.0f - C) * outL; //find half of total area float halfArea = (area1 + area2 + area3 + area4 + area5) / 2; //determine which region split will be within and resulting horizontal midpoint //Within area 1 if( area1 > halfArea ) { clusters[cluster].beta = 0.5f + (float)sqrt(2*halfArea); } //Within area 2 else if( area1 + area2 > halfArea ) { clusters[cluster].beta = ((halfArea - area1) / outM) + A; } //Within area 3-4 else if( area1 + area2 + area3 + area4 > halfArea ) { float a = 1.0f/3.0f; float b = outM - 0.5f - D/3; float c = area1 + area2 - D*outM + D/2 - halfArea; clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); } //Within area5 else { clusters[cluster].beta = ((halfArea - (area1 + area2 + area3 + area4) ) / outL) + C; } } //end case 2 //--------------------------------------------------------------- //Case 3 else { //find area of 5 subregions float area1 = (outM*(A-0.5f)) / 2; float area2 = (B-A) * outM; float area3 = ((E-B) * (outM - outL)) / 2; float area4 = (E-B) * outL; float area5 = (3.0f - E) * outL; //find half of total area float halfArea = (area1 + area2 + area3 + area4 + area5) / 2; //determine which region split will be within and resulting horizontal midpoint //Within area 1 if( area1 > halfArea ) { clusters[cluster].beta = 0.5f + (float)sqrt(2*halfArea); } //Within area 2 else if( area1 + area2 > halfArea ) { clusters[cluster].beta = ((halfArea - area1) / outM) + A; } //Within area 3-4 else if( area1 + area2 + area3 + area4 > halfArea ) { float a = -0.5f; float b = E/2 + 2.5f/2; float c = area3 - 2.5f*E/2; clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); } //Within area5 else { clusters[cluster].beta = ((halfArea - (area1 + area2 + area3 + area4) ) / outL) + E; } } //end case 3 //--------------------------------------------------------------- //Compute edge threshold int lumJND = 255/50; clusters[cluster].edgeThreshold = clusters[cluster].mode + clusters[cluster].beta*lumJND; } //end for cluster }
void EdgeDetect::computeEdgeMagAndGSLCmaps | ( | ) | [private] |
Definition at line 341 of file edgeDetect.cpp.
References edgeMagMap, GSLCmap, image, and pixelLum().
Referenced by EdgeDetect().
{ int x, y; int idealPattern[9]; int pixelLums[9]; //------- //iterate over all pixels for( y=0; y<image->height(); y++) { for( x=0; x<image->width(); x++) { //compute pixel luminances for entire grid pixelLums[0] = pixelLum(x-1,y-1); pixelLums[1] = pixelLum(x ,y-1); pixelLums[2] = pixelLum(x+1,y-1); pixelLums[3] = pixelLum(x-1,y ); pixelLums[4] = pixelLum(x ,y ); pixelLums[5] = pixelLum(x+1,y ); pixelLums[6] = pixelLum(x-1,y+1); pixelLums[7] = pixelLum(x ,y+1); pixelLums[8] = pixelLum(x+1,y+1); //compute average float avg = 0; int i; for(i=0; i<=8; i++) { avg+= pixelLums[i]; } avg = avg / 9; //determine ideal pattern and I0 and I1 averages int centerPixelLum = pixelLums[4]; float centerDiff = centerPixelLum - avg; float I0avg = 0; int I0count = 0; float I1avg = 0; int I1count = 0; for(i=0; i<=8; i++) { if( centerDiff * (pixelLums[i]-avg) >=0 ) { I1avg+=pixelLums[i]; I1count++; idealPattern[i] = 1; } else { I0avg+=pixelLums[i]; I0count++; idealPattern[i] = 0; } } //compute and store edge magnitude if(I0count > 0) I0avg = I0avg/I0count; if(I1count > 0) I1avg = I1avg/I1count; edgeMagMap[x + y*image->width()] = QABS( I1avg - I0avg ); //compute and store GSLC int GSLC=0; int weight = 1; for(i=0; i<9; i++) { //skip center if(i == 4) continue; if(idealPattern[i] == 1) { GSLC+=weight; } weight = weight*2; } GSLCmap[x + y*image->width()] = GSLC; } //x } //y }
void EdgeDetect::constructEdgeImage | ( | ) | [private] |
Definition at line 859 of file edgeDetect.cpp.
References blurImage(), clusters, LUTentry::direction, edgeMagMap, PixelCluster::edgeThreshold, enhanceImageContrast(), LUTentry::ESF, GSLCmap, height, image, lumMap, LUT, numClusters, and width.
Referenced by EdgeDetect().
{ int x, y; QRgb* rgb; uchar* scanLine; for( y=0; y<image->height(); y++) { scanLine = image->scanLine(y); for( x=0; x<image->width(); x++) { //initialize pixel to black rgb = ((QRgb*)scanLine+x); *rgb = qRgb( 0, 0, 0 ); //lookup ESF for this pixel float ESF = LUT[ GSLCmap[x + y*image->width()] ].ESF; //If ESF value for this pixel is 0 skip if( ESF == 0.0f ) continue; //lookup edge magnitude threshold float lum = lumMap[x + y*image->width()]; float edgeMagThresh = -1.0f; int cluster; for(cluster=0; cluster<numClusters; cluster++) { if(lum >= clusters[cluster].minLuminance && lum <= clusters[cluster].maxLuminance) { edgeMagThresh = clusters[cluster].edgeThreshold; break; } } //if cluster not found bail if( cluster >= numClusters ) { // cout << "Error! Could not find cluster pixel belonged to!\n"; continue; } //if edge mag below thresh then skip if( edgeMagMap[x + y*image->width()] < edgeMagThresh ) continue; //ok, last checks implement NMS (non-maximum supression) int direction = LUT[ GSLCmap[x + y*image->width()] ].direction; int neighborIndex1 = -1; int neighborIndex2 = -1; if( direction == 0) { if( x > 0) neighborIndex1 = x-1 + y*image->width(); if( x < image->width() - 1 ) neighborIndex2 = x+1 + y*image->width(); } else if(direction == 1) { if( x > 0 && y < image->height() - 1 ) neighborIndex1 = x-1 + (y+1)*image->width(); if( x < image->width() - 1 && y > 0 ) neighborIndex2 = x+1 + (y-1)*image->width(); } else if(direction == 2) { if( y < image->height() - 1 ) neighborIndex1 = x + (y+1)*image->width(); if( y > 0) neighborIndex2 = x + (y-1)*image->width(); } else if(direction == 3) { if( x < image->width() - 1 && y < image->height() - 1 ) neighborIndex1 = x+1 + (y+1)*image->width(); if( x > 0 && y > 0 ) neighborIndex2 = x-1 + (y-1)*image->width(); } //neighbor 1 has higher confidence, skip! if( neighborIndex1 != -1 && LUT[ GSLCmap[neighborIndex1] ].ESF * edgeMagMap[neighborIndex1] > ESF * edgeMagMap[x + y*image->width()] ) continue; //neighbor 2 has higher confidence, skip! if( neighborIndex2 != -1 && LUT[ GSLCmap[neighborIndex2] ].ESF * edgeMagMap[neighborIndex2] > ESF * edgeMagMap[x + y*image->width()] ) continue; //All tests passed! Mark edge! *rgb = qRgb( 255, 255, 255 ); } //x } //y //blur image - all of it blurImage( *image, 2.0f ); //normalize image enhanceImageContrast( image ); }
void EdgeDetect::constructGSLClut | ( | ) | [private] |
Definition at line 971 of file edgeDetect.cpp.
References LUTentry::direction, LUTentry::ESF, and LUT.
Referenced by allocateAndInitObjects().
{ //---------------------- //First fill entire table with 0 ESF's and invalid directions int i; for(i=0; i<256; i++) { LUT[i].ESF = 0.0f; LUT[i].direction = -1; } //---------------------- //Next code in all pattern that are highly //likely to be on edges as described in the paper //---------------------- //Pattern (a) // ### // ##. // ... LUT[15].ESF = 0.179f; LUT[15].direction = 3; // ... // .## // ### LUT[240].ESF = 0.179f; LUT[240].direction = 3; // ### // .## // ... LUT[23].ESF = 0.179f; LUT[23].direction = 1; // ... // ##. // ### LUT[232].ESF = 0.179f; LUT[232].direction = 1; // ##. // ##. // #.. LUT[43].ESF = 0.179f; LUT[43].direction = 3; // ..# // .## // .## LUT[212].ESF = 0.179f; LUT[212].direction = 3; // #.. // ##. // ##. LUT[105].ESF = 0.179f; LUT[105].direction = 1; // .## // .## // ..# LUT[150].ESF = 0.179f; LUT[150].direction = 1; //---------------------- //Pattern (b) // ### // ### // ... LUT[31].ESF = 0.137f; LUT[31].direction = 2; // ... // ### // ### LUT[248].ESF = 0.137f; LUT[248].direction = 2; // ##. // ##. // ##. LUT[107].ESF = 0.137f; LUT[107].direction = 0; // .## // .## // .## LUT[214].ESF = 0.137f; LUT[214].direction = 0; //---------------------- //Pattern (c) // ### // .#. // ... LUT[7].ESF = 0.126f; LUT[7].direction = 2; // ... // .#. // ### LUT[224].ESF = 0.126f; LUT[224].direction = 2; // #.. // ##. // #.. LUT[41].ESF = 0.126f; LUT[41].direction = 0; // ..# // .## // ..# LUT[148].ESF = 0.126f; LUT[148].direction = 0; //---------------------- //Pattern (d) // ### // ##. // #.. LUT[47].ESF = 0.10f; LUT[47].direction = 3; // ..# // .## // ### LUT[244].ESF = 0.10f; LUT[244].direction = 3; // ### // .## // ..# LUT[151].ESF = 0.10f; LUT[151].direction = 1; // #.. // ##. // ### LUT[233].ESF = 0.10f; LUT[233].direction = 1; //---------------------- //Pattern (e) // ##. // ##. // ... LUT[11].ESF = 0.10f; LUT[11].direction = 3; // ... // .## // .## LUT[208].ESF = 0.10f; LUT[208].direction = 3; // .## // .## // ... LUT[22].ESF = 0.10f; LUT[22].direction = 1; // ... // ##. // ##. LUT[104].ESF = 0.10f; LUT[104].direction = 1; //---------------------- }
void EdgeDetect::deallocateObjects | ( | ) | [private] |
Definition at line 963 of file edgeDetect.cpp.
References clusters, edgeMagMap, GSLCmap, and lumMap.
Referenced by ~EdgeDetect().
{ delete[] lumMap; lumMap = NULL; delete[] edgeMagMap; edgeMagMap = NULL; delete[] GSLCmap; GSLCmap = NULL; delete[] clusters; clusters = NULL; }
void EdgeDetect::fillLumMapAndLumHistogram | ( | ) | [private] |
Definition at line 291 of file edgeDetect.cpp.
References image, lumHist, and lumMap.
Referenced by EdgeDetect().
{ int x, y; QRgb* rgb; uchar* scanLine; int lumVal; for( y=0; y<image->height(); y++) { scanLine = image->scanLine(y); for( x=0; x<image->width(); x++) { //get lum value for this pixel rgb = ((QRgb*)scanLine+x); lumVal = qGray(*rgb); //store in lum map lumMap[x + y*image->width()] = lumVal; //update lum histogram lumHist[ lumVal ]++; } } }
void EdgeDetect::findPixelClusters | ( | ) | [private] |
Definition at line 429 of file edgeDetect.cpp.
References clusterPeaks, clusters, PixelCluster::maxLuminance, PixelCluster::minLuminance, numClusters, and smoothLumHist.
Referenced by EdgeDetect().
{ //find max count int maxCount = 0; int i; for(i=0; i<256; i++) { if(smoothLumHist[i] > maxCount) maxCount = smoothLumHist[i]; } //compute JND for histogram (2% of total spread) int histJND = maxCount/50; //construct temporary array for valley locations //1's will indicate a valley midpoint int tmpValleyArray[256]; for(i=0; i<256; i++) { tmpValleyArray[i] = 0; } //move across histogram finding valley midpoints int curTrackedMin = smoothLumHist[0]; //first and last indices tracked min was observed int firstMinIndex = 0; int lastMinIndex = 0; //only add valley midpoint if finished tracking a descent bool slopeNeg = false; for(i = 1; i<256; i++ ) { if( smoothLumHist[i] < curTrackedMin - histJND ) { //found a descent! slopeNeg = true; curTrackedMin = smoothLumHist[i]; firstMinIndex = i; } //starting to go up again, add last min to list else if( smoothLumHist[i] > curTrackedMin + histJND ) { //if finished tracing a negative slope find midpoint and set location to true if(slopeNeg) { tmpValleyArray[ (firstMinIndex + lastMinIndex)/2 ] = 1; } curTrackedMin = smoothLumHist[i]; slopeNeg = false; } else { //still tracking a min, update the right //hand index. center of valley is found //by averaging first and last min index lastMinIndex = i; } } //count valleys int numValleys = 0; for(i=0; i<256; i++) { if(tmpValleyArray[i] == 1 ) numValleys++; } //determine number of clusters numClusters = numValleys-1; if(tmpValleyArray[0] != 1) numClusters++; if(tmpValleyArray[255] != 1) numClusters++; //allocate clusters clusters = new PixelCluster[numClusters]; //automatically start first cluster int cluster=0; clusters[cluster].minLuminance = 0; //initialize left and right boundaries of all clusters for(i=1; i<256; i++) { //reached next valley, end cluster if( tmpValleyArray[i] == 1) { clusters[cluster].maxLuminance = i-1; cluster++; clusters[cluster].minLuminance = i; } //end last cluster automatically at end else if(i == 255) { clusters[cluster].maxLuminance = i; } } //determine cluster peaks for(cluster=0; cluster<numClusters; cluster++) { //find max for current cluster int maxIndex = clusters[cluster].minLuminance; for(i=clusters[cluster].minLuminance; i<=clusters[cluster].maxLuminance; i++) { if(smoothLumHist[i] > smoothLumHist[maxIndex]) maxIndex = i; } //mark peaks int lumJND = 255/50; for(i=QMAX(0, maxIndex-lumJND); i<QMIN(256, maxIndex+lumJND); i++) { clusterPeaks[i] = 1; } } }
int * EdgeDetect::getClusterMap | ( | ) |
Definition at line 241 of file edgeDetect.cpp.
References clusters, image, lumMap, and numClusters.
Referenced by GrainEditor::GrainEditor().
{ //construct map int* clusterMap = new int[image->width() * image->height()]; //iterate over all pixels, determine cluster each pixel belongs to int i, cluster; for(i=0; i<image->width()*image->height(); i++) { for(cluster=0; cluster<numClusters; cluster++) { if( lumMap[i] >= clusters[cluster].minLuminance && lumMap[i] <= clusters[cluster].maxLuminance ) { clusterMap[i] = cluster; break; } } //cluster } //pixel return clusterMap; }
PixelCluster * EdgeDetect::getClusters | ( | ) |
QImage * EdgeDetect::getEdgeImage | ( | ) |
int EdgeDetect::getNumClusters | ( | ) |
Definition at line 224 of file edgeDetect.cpp.
References numClusters.
Referenced by GrainEditor::GrainEditor().
{ return numClusters; }
int * EdgeDetect::getPeaks | ( | ) |
int * EdgeDetect::getSmoothHist | ( | ) |
int EdgeDetect::pixelLum | ( | int | x, |
int | y | ||
) | [private] |
Definition at line 422 of file edgeDetect.cpp.
Referenced by computeEdgeMagAndGSLCmaps().
void EdgeDetect::smoothLumHistogram | ( | ) | [private] |
Definition at line 315 of file edgeDetect.cpp.
References FILTER_SIZE, lumHist, and smoothLumHist.
Referenced by EdgeDetect().
{ #define FILTER_SIZE 5 int filter[FILTER_SIZE] = {2, 5, 8, 5, 2}; int i,j; int filterIndex, sum, total; for(i = 0; i<256; i++) { sum = 0; total = 0; for( j= -FILTER_SIZE/2; j <= FILTER_SIZE/2; j++) { if( i+j > 0 && i+j < 256 ) { filterIndex = j+ FILTER_SIZE/2; total+= filter[filterIndex] * lumHist[i+j]; sum += filter[filterIndex]; } } smoothLumHist[i] = total / sum; } }
int EdgeDetect::clusterPeaks[256] [private] |
Definition at line 100 of file edgeDetect.h.
Referenced by allocateAndInitObjects(), computeClusterStatistics(), findPixelClusters(), and getPeaks().
PixelCluster* EdgeDetect::clusters [private] |
Definition at line 113 of file edgeDetect.h.
Referenced by computeClusterStatistics(), computeClusterThresholds(), constructEdgeImage(), deallocateObjects(), findPixelClusters(), getClusterMap(), and getClusters().
float* EdgeDetect::edgeMagMap [private] |
Definition at line 106 of file edgeDetect.h.
Referenced by allocateAndInitObjects(), computeClusterStatistics(), computeEdgeMagAndGSLCmaps(), constructEdgeImage(), and deallocateObjects().
int* EdgeDetect::GSLCmap [private] |
Definition at line 109 of file edgeDetect.h.
Referenced by allocateAndInitObjects(), computeEdgeMagAndGSLCmaps(), constructEdgeImage(), and deallocateObjects().
QImage* EdgeDetect::image [private] |
Definition at line 93 of file edgeDetect.h.
Referenced by allocateAndInitObjects(), computeClusterStatistics(), computeEdgeMagAndGSLCmaps(), constructEdgeImage(), EdgeDetect(), fillLumMapAndLumHistogram(), getClusterMap(), getEdgeImage(), and pixelLum().
int EdgeDetect::lumHist[256] [private] |
luminosity and smooth luminosity histograms
Definition at line 96 of file edgeDetect.h.
Referenced by allocateAndInitObjects(), fillLumMapAndLumHistogram(), and smoothLumHistogram().
int* EdgeDetect::lumMap [private] |
Definition at line 103 of file edgeDetect.h.
Referenced by allocateAndInitObjects(), computeClusterStatistics(), constructEdgeImage(), deallocateObjects(), fillLumMapAndLumHistogram(), getClusterMap(), and pixelLum().
LUTentry EdgeDetect::LUT[256] [private] |
Definition at line 90 of file edgeDetect.h.
Referenced by constructEdgeImage(), and constructGSLClut().
int EdgeDetect::maxClusterSize [private] |
Definition at line 116 of file edgeDetect.h.
Referenced by computeClusterStatistics().
int EdgeDetect::minClusterSize [private] |
Definition at line 116 of file edgeDetect.h.
Referenced by computeClusterStatistics().
int EdgeDetect::numClusters [private] |
Definition at line 112 of file edgeDetect.h.
Referenced by computeClusterStatistics(), computeClusterThresholds(), constructEdgeImage(), findPixelClusters(), getClusterMap(), and getNumClusters().
int EdgeDetect::smoothLumHist[256] [private] |
Definition at line 97 of file edgeDetect.h.
Referenced by allocateAndInitObjects(), findPixelClusters(), getSmoothHist(), and smoothLumHistogram().