Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

EdgeDetect Class Reference

#include <edgeDetect.h>

Collaboration diagram for EdgeDetect:

[legend]
List of all members.

Public Member Functions

 EdgeDetect (QImage *image)
 ~EdgeDetect ()
int getNumClusters ()
PixelClustergetClusters ()
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
PixelClusterclusters
int minClusterSize
int maxClusterSize

Constructor & Destructor Documentation

EdgeDetect::EdgeDetect QImage *  image  ) 
 

Definition at line 192 of file edgeDetect.cpp.

References allocateAndInitObjects(), computeClusterStatistics(), computeClusterThresholds(), computeEdgeMagAndGSLCmaps(), constructEdgeImage(), EdgeDetect(), fillLumMapAndLumHistogram(), findPixelClusters(), and smoothLumHistogram().

Referenced by EdgeDetect().

00193 { 00194 //load image 00195 this->image = image; 00196 00197 //allocate and initialize objects used for edge detection 00198 allocateAndInitObjects(); 00199 00200 //fill lum map and lum histogram 00201 fillLumMapAndLumHistogram(); 00202 00203 //fill smoothed histogram 00204 smoothLumHistogram(); 00205 00206 //compute edge magnitude and GSLC maps 00207 computeEdgeMagAndGSLCmaps(); 00208 00209 //determine pixel clusters 00210 findPixelClusters(); 00211 00212 computeClusterStatistics(); 00213 00214 computeClusterThresholds(); 00215 00216 constructEdgeImage(); 00217 }

EdgeDetect::~EdgeDetect  ) 
 

Definition at line 219 of file edgeDetect.cpp.

References deallocateObjects().

00220 { 00221 deallocateObjects(); 00222 }


Member Function Documentation

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

00265 { 00266 //initialize: 00267 //-luminosity histogram 00268 //-smoothed luminosity histogram 00269 //-identified peak regions 00270 int i; 00271 for(i=0; i<256; i++) 00272 { 00273 lumHist[i] = 0; 00274 smoothLumHist[i] = 0; 00275 clusterPeaks[i] = 0; 00276 } 00277 00278 //allocate luminance map 00279 lumMap = new int[image->width() * image->height()]; 00280 00281 //allocate edge magnitude map 00282 edgeMagMap = new float[image->width() * image->height()]; 00283 00284 //allocate GSLC map 00285 GSLCmap = new int[image->width() * image->height()]; 00286 00287 //construct LUT 00288 constructGSLClut(); 00289 }

void EdgeDetect::computeClusterStatistics  )  [private]
 

Definition at line 546 of file edgeDetect.cpp.

References clusterPeaks, clusters, PixelCluster::edgeMagHistogram, edgeMagMap, image, lumMap, maxClusterSize, minClusterSize, PixelCluster::minLuminance, numClusters, PixelCluster::numPixels, and PixelCluster::totalEdgeMagnitude.

Referenced by EdgeDetect().

00547 { 00548 //initialize cluster stats 00549 int cluster; 00550 for(cluster=0; cluster<numClusters; cluster++) 00551 { 00552 int i; 00553 for(i=0; i<256; i++) 00554 { 00555 clusters[cluster].edgeMagHistogram[i] = 0; 00556 } 00557 clusters[cluster].totalEdgeMagnitude=0.0f; 00558 clusters[cluster].numPixels = 0; 00559 } 00560 00561 //iterate over all pixels 00562 int i; 00563 for(i=0; i<image->width()*image->height(); i++) 00564 { 00565 //skip pixels that don't belong to peaks 00566 if( clusterPeaks[ lumMap[i] ] != 1) 00567 continue; 00568 00569 //determine cluster pixel belongs to 00570 int cluster; 00571 for(cluster=0; cluster<numClusters; cluster++) 00572 { 00573 if( lumMap[i] >= clusters[cluster].minLuminance && 00574 lumMap[i] <= clusters[cluster].maxLuminance ) 00575 { 00576 clusters[cluster].totalEdgeMagnitude+= edgeMagMap[i]; 00577 clusters[cluster].numPixels++; 00578 clusters[cluster].edgeMagHistogram[ QMIN( QMAX( (int)edgeMagMap[i], 0), 255) ]++; 00579 break; 00580 } 00581 } //cluster 00582 } //pixel i 00583 00584 //iterate over clusters to determine min and max peak cluster sizes 00585 minClusterSize = clusters[0].numPixels; 00586 maxClusterSize = clusters[0].numPixels; 00587 for(cluster=1; cluster<numClusters; cluster++) 00588 { 00589 if(clusters[cluster].numPixels < minClusterSize) 00590 minClusterSize = clusters[cluster].numPixels; 00591 00592 if(clusters[cluster].numPixels > maxClusterSize) 00593 maxClusterSize = clusters[cluster].numPixels; 00594 } 00595 00596 //iterate over clusters one final time to deduce normalized inputs to fuzzy logic process 00597 int JND = 255/50; 00598 for(cluster=0; cluster<numClusters; cluster++) 00599 { 00600 clusters[cluster].meanMode = QMIN( clusters[cluster].totalEdgeMagnitude / clusters[cluster].numPixels, 00601 3*JND ); 00602 00603 int i; 00604 int mode = 0; 00605 for(i=1; i<256; i++) 00606 { 00607 if( clusters[cluster].edgeMagHistogram[i] > clusters[cluster].edgeMagHistogram[ mode ] ) 00608 mode = i; 00609 } 00610 clusters[cluster].mode = QMIN( mode, 2*JND ); 00611 00612 clusters[cluster].pixelCount = ((float)(clusters[cluster].numPixels - minClusterSize)) / 00613 (maxClusterSize - minClusterSize); 00614 } 00615 }

void EdgeDetect::computeClusterThresholds  )  [private]
 

Definition at line 618 of file edgeDetect.cpp.

References b, B, PixelCluster::beta, clusters, PixelCluster::edgeThreshold, PixelCluster::meanMode, PixelCluster::mode, and numClusters.

Referenced by EdgeDetect().

00619 { 00620 //iterate over each cluster 00621 int cluster; 00622 float S1,M1,L1; 00623 float S2,M2,L2; 00624 float S3,L3; 00625 float outS, outM, outL; 00626 00627 int JND = 255/50; 00628 00629 for(cluster=0; cluster<numClusters; cluster++) 00630 { 00631 //---- 00632 //compute S,M, and L values for each input 00633 //---- 00634 S1 = QMAX( 1.0f - ((clusters[cluster].meanMode/JND) / 1.5f), 0 ); 00635 00636 if( (clusters[cluster].meanMode/JND) <= 1.5f ) 00637 M1 = QMAX( (clusters[cluster].meanMode/JND) - 0.5f, 0 ); 00638 else 00639 M1 = QMAX( 2.5f - (clusters[cluster].meanMode/JND), 0 ); 00640 00641 L1 = QMAX( ((clusters[cluster].meanMode/JND) - 1.5f) / 1.5f, 0 ); 00642 //---- 00643 S2 = QMAX( 1.0f - (clusters[cluster].mode/JND), 0 ); 00644 00645 if( (clusters[cluster].mode/JND) <= 1.0f ) 00646 M2 = QMAX( -1.0f + 2*(clusters[cluster].mode/JND), 0 ); 00647 else 00648 M2 = QMAX( 3.0f - 2*(clusters[cluster].mode/JND), 0 ); 00649 00650 L2 = QMAX( (clusters[cluster].mode/JND) - 1.0, 0 ); 00651 //---- 00652 S3 = QMAX( 1.0f - 2*clusters[cluster].pixelCount, 0 ); 00653 L3 = QMAX( -1.0f + 2*clusters[cluster].pixelCount, 0 ); 00654 //---- 00655 00656 //Compute M,L for outputs using set of 18 rules. 00657 //outS is inherantly S given the ruleset provided 00658 outS = 0.0f; 00659 outM = 0.0f; 00660 outL = 0.0f; 00661 //Out 1 00662 if( numClusters > 2 ) 00663 { 00664 outM += S1*S2*S3; //rule 1 00665 00666 //rule 2 00667 if( clusters[cluster].meanMode < clusters[cluster].mode ) 00668 outS += S1*S2*L3; 00669 else 00670 outM += S1*S2*L3; 00671 00672 outM += S1*M2*S3; //rule 3 00673 outM += S1*M2*L3; //rule 4 00674 outM += S1*L2*S3; //rule 5 00675 outM += S1*L2*L3; //rule 6 00676 outM += M1*S2*S3; //rule 7 00677 outM += M1*S2*L3; //rule 8 00678 outM += M1*M2*S3; //rule 9 00679 outL += M1*M2*L3; //rule 10 00680 outM += M1*L2*S3; //rule 11 00681 outL += M1*L2*L3; //rule 12 00682 outM += L1*S2*S3; //rule 13 00683 outL += L1*S2*L3; //rule 14 00684 outM += L1*M2*S3; //rule 15 00685 outL += L1*M2*L3; //rule 16 00686 outL += L1*L2*S3; //rule 17 00687 outL += L1*L2*L3; //rule 18 00688 } 00689 //Out 2 00690 else 00691 { 00692 outL += S1*S2*S3; //rule 1 00693 outL += S1*S2*L3; //rule 2 00694 outM += S1*M2*S3; //rule 3 00695 outL += S1*M2*L3; //rule 4 00696 outM += S1*L2*S3; //rule 5 00697 outM += S1*L2*L3; //rule 6 00698 outL += M1*S2*S3; //rule 7 00699 outL += M1*S2*L3; //rule 8 00700 outL += M1*M2*S3; //rule 9 00701 outL += M1*M2*L3; //rule 10 00702 outL += M1*L2*S3; //rule 11 00703 outL += M1*L2*L3; //rule 12 00704 outL += L1*S2*S3; //rule 13 00705 outL += L1*S2*L3; //rule 14 00706 outL += L1*M2*S3; //rule 15 00707 outL += L1*M2*L3; //rule 16 00708 outL += L1*L2*S3; //rule 17 00709 outL += L1*L2*L3; //rule 18 00710 } 00711 00712 //find centroid - Beta[k] 00713 float A = outM + 0.5f; 00714 float B = 2.5f - outM; 00715 float C = 1.5f * (outL + 1); 00716 float D = 1.5f * (outM + 1); 00717 float E = 2.5f - outL; 00718 00719 //--------------------------------------------------------------- 00720 //Case 1: Both outM and outL are above intersection point of diagonals 00721 if( outM > 0.5f && outL > 0.5f ) 00722 { 00723 //find area of 7 subregions 00724 float area1 = ((A-0.5f)*outM)/2; 00725 float area2 = outM * (B-A); 00726 float area3 = ((2.1f-B) * (outM - 0.5)) / 2; 00727 float area4 = (2.1 - B) * 0.5f; 00728 float area5 = ((C - 2.1f) * (outL - 0.5)) / 2; 00729 float area6 = (C - 2.1f) * 0.5f; 00730 float area7 = (3.0f - C) * outL; 00731 00732 //find half of total area 00733 float halfArea = (area1 + area2 + area3 + area4 + area5 + area6 + area7) / 2; 00734 00735 //determine which region split will be within and resulting horizontal midpoint 00736 00737 //Within area 1 00738 if( area1 > halfArea ) 00739 { 00740 clusters[cluster].beta = 0.5f + (float)sqrt(2*halfArea); 00741 } 00742 //Within area 2 00743 else if( area1 + area2 > halfArea ) 00744 { 00745 clusters[cluster].beta = ((halfArea - area1) / outM) + A; 00746 } 00747 //Within area 3-4 00748 else if( area1 + area2 + area3 + area4 > halfArea ) 00749 { 00750 float a = -0.5f; 00751 float b = 2.8f; 00752 float c = area1 + area2 + area3 - halfArea - B/2 - 2.625f; 00753 clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); 00754 } 00755 //Within area 5-6 00756 else if( area1 + area2 + area3 + area4 + area5 + area6 > halfArea ) 00757 { 00758 float a = 1.0f/3; 00759 float b = -0.7f; 00760 float c = area1 + area2 + area3 + area4 - halfArea; 00761 clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); 00762 } 00763 //Within area 7 00764 else 00765 { 00766 clusters[cluster].beta = ((halfArea - (area1 + area2 + area3 + area4 + area5 + area6) ) / outL) + C; 00767 } 00768 } //end case 1 00769 //--------------------------------------------------------------- 00770 //Case 2 00771 else if ( outM < 0.5f && outL > outM ) 00772 { 00773 //find area of 5 subregions 00774 float area1 = (outM*(A-0.5f)) / 2; 00775 float area2 = (D-A) * outM; 00776 float area3 = ((C-D) * (outL - outM)) / 2; 00777 float area4 = (C-D) * outM; 00778 float area5 = (3.0f - C) * outL; 00779 00780 //find half of total area 00781 float halfArea = (area1 + area2 + area3 + area4 + area5) / 2; 00782 00783 //determine which region split will be within and resulting horizontal midpoint 00784 00785 //Within area 1 00786 if( area1 > halfArea ) 00787 { 00788 clusters[cluster].beta = 0.5f + (float)sqrt(2*halfArea); 00789 } 00790 //Within area 2 00791 else if( area1 + area2 > halfArea ) 00792 { 00793 clusters[cluster].beta = ((halfArea - area1) / outM) + A; 00794 } 00795 //Within area 3-4 00796 else if( area1 + area2 + area3 + area4 > halfArea ) 00797 { 00798 float a = 1.0f/3.0f; 00799 float b = outM - 0.5f - D/3; 00800 float c = area1 + area2 - D*outM + D/2 - halfArea; 00801 clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); 00802 } 00803 //Within area5 00804 else 00805 { 00806 clusters[cluster].beta = ((halfArea - (area1 + area2 + area3 + area4) ) / outL) + C; 00807 } 00808 } //end case 2 00809 //--------------------------------------------------------------- 00810 //Case 3 00811 else 00812 { 00813 //find area of 5 subregions 00814 float area1 = (outM*(A-0.5f)) / 2; 00815 float area2 = (B-A) * outM; 00816 float area3 = ((E-B) * (outM - outL)) / 2; 00817 float area4 = (E-B) * outL; 00818 float area5 = (3.0f - E) * outL; 00819 00820 //find half of total area 00821 float halfArea = (area1 + area2 + area3 + area4 + area5) / 2; 00822 00823 //determine which region split will be within and resulting horizontal midpoint 00824 00825 //Within area 1 00826 if( area1 > halfArea ) 00827 { 00828 clusters[cluster].beta = 0.5f + (float)sqrt(2*halfArea); 00829 } 00830 //Within area 2 00831 else if( area1 + area2 > halfArea ) 00832 { 00833 clusters[cluster].beta = ((halfArea - area1) / outM) + A; 00834 } 00835 //Within area 3-4 00836 else if( area1 + area2 + area3 + area4 > halfArea ) 00837 { 00838 float a = -0.5f; 00839 float b = E/2 + 2.5f/2; 00840 float c = area3 - 2.5f*E/2; 00841 clusters[cluster].beta = (-b + (float)sqrt( b*b - 4*a*c )) / (2*a); 00842 } 00843 //Within area5 00844 else 00845 { 00846 clusters[cluster].beta = ((halfArea - (area1 + area2 + area3 + area4) ) / outL) + E; 00847 } 00848 } //end case 3 00849 //--------------------------------------------------------------- 00850 00851 //Compute edge threshold 00852 int lumJND = 255/50; 00853 clusters[cluster].edgeThreshold = clusters[cluster].mode + clusters[cluster].beta*lumJND; 00854 00855 } //end for cluster 00856 00857 }

void EdgeDetect::computeEdgeMagAndGSLCmaps  )  [private]
 

Definition at line 341 of file edgeDetect.cpp.

References edgeMagMap, GSLCmap, image, and pixelLum().

Referenced by EdgeDetect().

00342 { 00343 int x, y; 00344 int idealPattern[9]; 00345 int pixelLums[9]; 00346 00347 //------- 00348 //iterate over all pixels 00349 for( y=0; y<image->height(); y++) 00350 { 00351 for( x=0; x<image->width(); x++) 00352 { 00353 //compute pixel luminances for entire grid 00354 pixelLums[0] = pixelLum(x-1,y-1); 00355 pixelLums[1] = pixelLum(x ,y-1); 00356 pixelLums[2] = pixelLum(x+1,y-1); 00357 pixelLums[3] = pixelLum(x-1,y ); 00358 pixelLums[4] = pixelLum(x ,y ); 00359 pixelLums[5] = pixelLum(x+1,y ); 00360 pixelLums[6] = pixelLum(x-1,y+1); 00361 pixelLums[7] = pixelLum(x ,y+1); 00362 pixelLums[8] = pixelLum(x+1,y+1); 00363 00364 //compute average 00365 float avg = 0; 00366 int i; 00367 for(i=0; i<=8; i++) 00368 { 00369 avg+= pixelLums[i]; 00370 } 00371 avg = avg / 9; 00372 00373 //determine ideal pattern and I0 and I1 averages 00374 int centerPixelLum = pixelLums[4]; 00375 float centerDiff = centerPixelLum - avg; 00376 00377 float I0avg = 0; 00378 int I0count = 0; 00379 00380 float I1avg = 0; 00381 int I1count = 0; 00382 00383 for(i=0; i<=8; i++) 00384 { 00385 if( centerDiff * (pixelLums[i]-avg) >=0 ) 00386 { 00387 I1avg+=pixelLums[i]; 00388 I1count++; 00389 idealPattern[i] = 1; 00390 } 00391 else 00392 { 00393 I0avg+=pixelLums[i]; 00394 I0count++; 00395 idealPattern[i] = 0; 00396 } 00397 } 00398 00399 //compute and store edge magnitude 00400 if(I0count > 0) I0avg = I0avg/I0count; 00401 if(I1count > 0) I1avg = I1avg/I1count; 00402 edgeMagMap[x + y*image->width()] = QABS( I1avg - I0avg ); 00403 00404 //compute and store GSLC 00405 int GSLC=0; 00406 int weight = 1; 00407 for(i=0; i<9; i++) 00408 { 00409 //skip center 00410 if(i == 4) continue; 00411 00412 if(idealPattern[i] == 1) 00413 { GSLC+=weight; } 00414 00415 weight = weight*2; 00416 } 00417 GSLCmap[x + y*image->width()] = GSLC; 00418 } //x 00419 } //y 00420 }

void EdgeDetect::constructEdgeImage  )  [private]
 

Definition at line 859 of file edgeDetect.cpp.

References blurImage(), clusters, edgeMagMap, enhanceImageContrast(), LUTentry::ESF, GSLCmap, image, lumMap, LUT, PixelCluster::minLuminance, and numClusters.

Referenced by EdgeDetect().

00860 { 00861 int x, y; 00862 QRgb* rgb; 00863 00864 uchar* scanLine; 00865 for( y=0; y<image->height(); y++) 00866 { 00867 scanLine = image->scanLine(y); 00868 for( x=0; x<image->width(); x++) 00869 { 00870 //initialize pixel to black 00871 rgb = ((QRgb*)scanLine+x); 00872 *rgb = qRgb( 0, 0, 0 ); 00873 00874 //lookup ESF for this pixel 00875 float ESF = LUT[ GSLCmap[x + y*image->width()] ].ESF; 00876 00877 //If ESF value for this pixel is 0 skip 00878 if( ESF == 0.0f ) continue; 00879 00880 //lookup edge magnitude threshold 00881 float lum = lumMap[x + y*image->width()]; 00882 float edgeMagThresh = -1.0f; 00883 int cluster; 00884 for(cluster=0; cluster<numClusters; cluster++) 00885 { 00886 if(lum >= clusters[cluster].minLuminance && 00887 lum <= clusters[cluster].maxLuminance) 00888 { 00889 edgeMagThresh = clusters[cluster].edgeThreshold; 00890 break; 00891 } 00892 } 00893 00894 //if cluster not found bail 00895 if( cluster >= numClusters ) 00896 { 00897 // cout << "Error! Could not find cluster pixel belonged to!\n"; 00898 continue; 00899 } 00900 00901 //if edge mag below thresh then skip 00902 if( edgeMagMap[x + y*image->width()] < edgeMagThresh ) continue; 00903 00904 //ok, last checks implement NMS (non-maximum supression) 00905 int direction = LUT[ GSLCmap[x + y*image->width()] ].direction; 00906 int neighborIndex1 = -1; 00907 int neighborIndex2 = -1; 00908 00909 if( direction == 0) 00910 { 00911 if( x > 0) 00912 neighborIndex1 = x-1 + y*image->width(); 00913 if( x < image->width() - 1 ) 00914 neighborIndex2 = x+1 + y*image->width(); 00915 } 00916 else if(direction == 1) 00917 { 00918 if( x > 0 && y < image->height() - 1 ) 00919 neighborIndex1 = x-1 + (y+1)*image->width(); 00920 if( x < image->width() - 1 && y > 0 ) 00921 neighborIndex2 = x+1 + (y-1)*image->width(); 00922 } 00923 else if(direction == 2) 00924 { 00925 if( y < image->height() - 1 ) 00926 neighborIndex1 = x + (y+1)*image->width(); 00927 if( y > 0) 00928 neighborIndex2 = x + (y-1)*image->width(); 00929 } 00930 else if(direction == 3) 00931 { 00932 if( x < image->width() - 1 && y < image->height() - 1 ) 00933 neighborIndex1 = x+1 + (y+1)*image->width(); 00934 if( x > 0 && y > 0 ) 00935 neighborIndex2 = x-1 + (y-1)*image->width(); 00936 } 00937 00938 //neighbor 1 has higher confidence, skip! 00939 if( neighborIndex1 != -1 && 00940 LUT[ GSLCmap[neighborIndex1] ].ESF * edgeMagMap[neighborIndex1] > 00941 ESF * edgeMagMap[x + y*image->width()] ) 00942 continue; 00943 00944 //neighbor 2 has higher confidence, skip! 00945 if( neighborIndex2 != -1 && 00946 LUT[ GSLCmap[neighborIndex2] ].ESF * edgeMagMap[neighborIndex2] > 00947 ESF * edgeMagMap[x + y*image->width()] ) 00948 continue; 00949 00950 //All tests passed! Mark edge! 00951 *rgb = qRgb( 255, 255, 255 ); 00952 } //x 00953 } //y 00954 00955 //blur image - all of it 00956 blurImage( *image, 2.0f ); 00957 00958 //normalize image 00959 enhanceImageContrast( image ); 00960 00961 }

void EdgeDetect::constructGSLClut  )  [private]
 

Definition at line 971 of file edgeDetect.cpp.

References LUTentry::direction, LUTentry::ESF, and LUT.

Referenced by allocateAndInitObjects().

00972 { 00973 //---------------------- 00974 //First fill entire table with 0 ESF's and invalid directions 00975 int i; 00976 for(i=0; i<256; i++) 00977 { 00978 LUT[i].ESF = 0.0f; 00979 LUT[i].direction = -1; 00980 } 00981 //---------------------- 00982 //Next code in all pattern that are highly 00983 //likely to be on edges as described in the paper 00984 //---------------------- 00985 //Pattern (a) 00986 00987 // ### 00988 // ##. 00989 // ... 00990 LUT[15].ESF = 0.179f; 00991 LUT[15].direction = 3; 00992 00993 // ... 00994 // .## 00995 // ### 00996 LUT[240].ESF = 0.179f; 00997 LUT[240].direction = 3; 00998 00999 // ### 01000 // .## 01001 // ... 01002 LUT[23].ESF = 0.179f; 01003 LUT[23].direction = 1; 01004 01005 // ... 01006 // ##. 01007 // ### 01008 LUT[232].ESF = 0.179f; 01009 LUT[232].direction = 1; 01010 01011 // ##. 01012 // ##. 01013 // #.. 01014 LUT[43].ESF = 0.179f; 01015 LUT[43].direction = 3; 01016 01017 // ..# 01018 // .## 01019 // .## 01020 LUT[212].ESF = 0.179f; 01021 LUT[212].direction = 3; 01022 01023 // #.. 01024 // ##. 01025 // ##. 01026 LUT[105].ESF = 0.179f; 01027 LUT[105].direction = 1; 01028 01029 // .## 01030 // .## 01031 // ..# 01032 LUT[150].ESF = 0.179f; 01033 LUT[150].direction = 1; 01034 //---------------------- 01035 //Pattern (b) 01036 01037 // ### 01038 // ### 01039 // ... 01040 LUT[31].ESF = 0.137f; 01041 LUT[31].direction = 2; 01042 01043 // ... 01044 // ### 01045 // ### 01046 LUT[248].ESF = 0.137f; 01047 LUT[248].direction = 2; 01048 01049 // ##. 01050 // ##. 01051 // ##. 01052 LUT[107].ESF = 0.137f; 01053 LUT[107].direction = 0; 01054 01055 // .## 01056 // .## 01057 // .## 01058 LUT[214].ESF = 0.137f; 01059 LUT[214].direction = 0; 01060 //---------------------- 01061 //Pattern (c) 01062 01063 // ### 01064 // .#. 01065 // ... 01066 LUT[7].ESF = 0.126f; 01067 LUT[7].direction = 2; 01068 01069 // ... 01070 // .#. 01071 // ### 01072 LUT[224].ESF = 0.126f; 01073 LUT[224].direction = 2; 01074 01075 // #.. 01076 // ##. 01077 // #.. 01078 LUT[41].ESF = 0.126f; 01079 LUT[41].direction = 0; 01080 01081 // ..# 01082 // .## 01083 // ..# 01084 LUT[148].ESF = 0.126f; 01085 LUT[148].direction = 0; 01086 //---------------------- 01087 //Pattern (d) 01088 01089 // ### 01090 // ##. 01091 // #.. 01092 LUT[47].ESF = 0.10f; 01093 LUT[47].direction = 3; 01094 01095 // ..# 01096 // .## 01097 // ### 01098 LUT[244].ESF = 0.10f; 01099 LUT[244].direction = 3; 01100 01101 // ### 01102 // .## 01103 // ..# 01104 LUT[151].ESF = 0.10f; 01105 LUT[151].direction = 1; 01106 01107 // #.. 01108 // ##. 01109 // ### 01110 LUT[233].ESF = 0.10f; 01111 LUT[233].direction = 1; 01112 //---------------------- 01113 //Pattern (e) 01114 01115 // ##. 01116 // ##. 01117 // ... 01118 LUT[11].ESF = 0.10f; 01119 LUT[11].direction = 3; 01120 01121 // ... 01122 // .## 01123 // .## 01124 LUT[208].ESF = 0.10f; 01125 LUT[208].direction = 3; 01126 01127 // .## 01128 // .## 01129 // ... 01130 LUT[22].ESF = 0.10f; 01131 LUT[22].direction = 1; 01132 01133 // ... 01134 // ##. 01135 // ##. 01136 LUT[104].ESF = 0.10f; 01137 LUT[104].direction = 1; 01138 //---------------------- 01139 }

void EdgeDetect::deallocateObjects  )  [private]
 

Definition at line 963 of file edgeDetect.cpp.

References clusters, edgeMagMap, GSLCmap, and lumMap.

Referenced by ~EdgeDetect().

00964 { 00965 delete[] lumMap; lumMap = NULL; 00966 delete[] edgeMagMap; edgeMagMap = NULL; 00967 delete[] GSLCmap; GSLCmap = NULL; 00968 delete[] clusters; clusters = NULL; 00969 }

void EdgeDetect::fillLumMapAndLumHistogram  )  [private]
 

Definition at line 291 of file edgeDetect.cpp.

References image, lumHist, and lumMap.

Referenced by EdgeDetect().

00292 { 00293 int x, y; 00294 QRgb* rgb; 00295 uchar* scanLine; 00296 int lumVal; 00297 for( y=0; y<image->height(); y++) 00298 { 00299 scanLine = image->scanLine(y); 00300 for( x=0; x<image->width(); x++) 00301 { 00302 //get lum value for this pixel 00303 rgb = ((QRgb*)scanLine+x); 00304 lumVal = qGray(*rgb); 00305 00306 //store in lum map 00307 lumMap[x + y*image->width()] = lumVal; 00308 00309 //update lum histogram 00310 lumHist[ lumVal ]++; 00311 } 00312 } 00313 }

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

00430 { 00431 //find max count 00432 int maxCount = 0; 00433 int i; 00434 for(i=0; i<256; i++) 00435 { 00436 if(smoothLumHist[i] > maxCount) 00437 maxCount = smoothLumHist[i]; 00438 } 00439 00440 //compute JND for histogram (2% of total spread) 00441 int histJND = maxCount/50; 00442 00443 //construct temporary array for valley locations 00444 //1's will indicate a valley midpoint 00445 int tmpValleyArray[256]; 00446 for(i=0; i<256; i++) { tmpValleyArray[i] = 0; } 00447 00448 //move across histogram finding valley midpoints 00449 int curTrackedMin = smoothLumHist[0]; 00450 00451 //first and last indices tracked min was observed 00452 int firstMinIndex = 0; 00453 int lastMinIndex = 0; 00454 00455 //only add valley midpoint if finished tracking a descent 00456 bool slopeNeg = false; 00457 00458 for(i = 1; i<256; i++ ) 00459 { 00460 if( smoothLumHist[i] < curTrackedMin - histJND ) 00461 { 00462 //found a descent! 00463 slopeNeg = true; 00464 curTrackedMin = smoothLumHist[i]; 00465 firstMinIndex = i; 00466 } 00467 //starting to go up again, add last min to list 00468 else if( smoothLumHist[i] > curTrackedMin + histJND ) 00469 { 00470 //if finished tracing a negative slope find midpoint and set location to true 00471 if(slopeNeg) 00472 { 00473 tmpValleyArray[ (firstMinIndex + lastMinIndex)/2 ] = 1; 00474 } 00475 00476 curTrackedMin = smoothLumHist[i]; 00477 slopeNeg = false; 00478 } 00479 else 00480 { 00481 //still tracking a min, update the right 00482 //hand index. center of valley is found 00483 //by averaging first and last min index 00484 lastMinIndex = i; 00485 } 00486 } 00487 00488 //count valleys 00489 int numValleys = 0; 00490 for(i=0; i<256; i++) 00491 { 00492 if(tmpValleyArray[i] == 1 ) numValleys++; 00493 } 00494 00495 //determine number of clusters 00496 numClusters = numValleys-1; 00497 if(tmpValleyArray[0] != 1) 00498 numClusters++; 00499 if(tmpValleyArray[255] != 1) 00500 numClusters++; 00501 00502 //allocate clusters 00503 clusters = new PixelCluster[numClusters]; 00504 00505 //automatically start first cluster 00506 int cluster=0; 00507 clusters[cluster].minLuminance = 0; 00508 00509 //initialize left and right boundaries of all clusters 00510 for(i=1; i<256; i++) 00511 { 00512 //reached next valley, end cluster 00513 if( tmpValleyArray[i] == 1) 00514 { 00515 clusters[cluster].maxLuminance = i-1; 00516 cluster++; 00517 clusters[cluster].minLuminance = i; 00518 } 00519 //end last cluster automatically at end 00520 else if(i == 255) 00521 { 00522 clusters[cluster].maxLuminance = i; 00523 } 00524 } 00525 00526 //determine cluster peaks 00527 for(cluster=0; cluster<numClusters; cluster++) 00528 { 00529 //find max for current cluster 00530 int maxIndex = clusters[cluster].minLuminance; 00531 for(i=clusters[cluster].minLuminance; i<=clusters[cluster].maxLuminance; i++) 00532 { 00533 if(smoothLumHist[i] > smoothLumHist[maxIndex]) 00534 maxIndex = i; 00535 } 00536 00537 //mark peaks 00538 int lumJND = 255/50; 00539 for(i=QMAX(0, maxIndex-lumJND); i<QMIN(256, maxIndex+lumJND); i++) 00540 { 00541 clusterPeaks[i] = 1; 00542 } 00543 } 00544 }

int * EdgeDetect::getClusterMap  ) 
 

Definition at line 241 of file edgeDetect.cpp.

References clusters, image, lumMap, PixelCluster::minLuminance, and numClusters.

Referenced by GrainEditor::GrainEditor().

00242 { 00243 //construct map 00244 int* clusterMap = new int[image->width() * image->height()]; 00245 00246 //iterate over all pixels, determine cluster each pixel belongs to 00247 int i, cluster; 00248 for(i=0; i<image->width()*image->height(); i++) 00249 { 00250 for(cluster=0; cluster<numClusters; cluster++) 00251 { 00252 if( lumMap[i] >= clusters[cluster].minLuminance && 00253 lumMap[i] <= clusters[cluster].maxLuminance ) 00254 { 00255 clusterMap[i] = cluster; 00256 break; 00257 } 00258 } //cluster 00259 } //pixel 00260 00261 return clusterMap; 00262 }

PixelCluster * EdgeDetect::getClusters  ) 
 

Definition at line 227 of file edgeDetect.cpp.

References clusters.

00228 { return clusters; }

QImage * EdgeDetect::getEdgeImage  ) 
 

Definition at line 236 of file edgeDetect.cpp.

References image.

00237 { 00238 return image; 00239 }

int EdgeDetect::getNumClusters  ) 
 

Definition at line 224 of file edgeDetect.cpp.

References numClusters.

Referenced by GrainEditor::GrainEditor().

00225 { return numClusters; }

int * EdgeDetect::getPeaks  ) 
 

Definition at line 230 of file edgeDetect.cpp.

References clusterPeaks.

00231 { return clusterPeaks; }

int * EdgeDetect::getSmoothHist  ) 
 

Definition at line 233 of file edgeDetect.cpp.

References smoothLumHist.

00234 { return smoothLumHist; }

int EdgeDetect::pixelLum int  x,
int  y
[private]
 

Definition at line 422 of file edgeDetect.cpp.

References image, lumMap, and pixelLum().

Referenced by computeEdgeMagAndGSLCmaps(), and pixelLum().

00423 { 00424 int clampedX = QMAX( QMIN( x, image->width()-1), 0); 00425 int clampedY = QMAX( QMIN( y, image->height()-1), 0); 00426 return lumMap[ clampedX + clampedY * image->width() ]; 00427 }

void EdgeDetect::smoothLumHistogram  )  [private]
 

Definition at line 315 of file edgeDetect.cpp.

References FILTER_SIZE, lumHist, and smoothLumHist.

Referenced by EdgeDetect().

00316 { 00317 #define FILTER_SIZE 5 00318 int filter[FILTER_SIZE] = {2, 5, 8, 5, 2}; 00319 00320 int i,j; 00321 int filterIndex, sum, total; 00322 for(i = 0; i<256; i++) 00323 { 00324 sum = 0; 00325 total = 0; 00326 00327 for( j= -FILTER_SIZE/2; j <= FILTER_SIZE/2; j++) 00328 { 00329 if( i+j > 0 && i+j < 256 ) 00330 { 00331 filterIndex = j+ FILTER_SIZE/2; 00332 total+= filter[filterIndex] * lumHist[i+j]; 00333 sum += filter[filterIndex]; 00334 } 00335 } 00336 00337 smoothLumHist[i] = total / sum; 00338 } 00339 }


Member Data Documentation

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


The documentation for this class was generated from the following files:
Generated on Sun Mar 4 19:43:05 2007 for AlbumShaper by doxygen 1.3.7