00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "Gist/SalientRegionSegmenter.H"
00041
00042 #include "Image/CutPaste.H"
00043 #include "Image/DrawOps.H"
00044 #include "Image/ColorOps.H"
00045 #include "Image/ShapeOps.H"
00046 #include "Image/Kernels.H"
00047 #include <cstdio>
00048
00049 #define MINIMUM_CONTOUR_LENGTH 5
00050
00051 #define LEN_WEIGHT .20 // contour boundary length weight
00052 #define SIM_WEIGHT .20 // similarity with closer side weight
00053 #define STR_WEIGHT .20 // strength of boundary weight
00054 #define RAT_WEIGHT .20 // ratio of in:out weight
00055 #define DIS_WEIGHT .20 // distance between sal pt and segment
00056
00057 #define NEIGHBORHOOD_RADIUS 12
00058
00059 #define MAX_FAR_TO_NEAR_RATIO 5.0
00060 #define MAX_DISTANCE .25 // quarter of the diagonal
00061
00062 #define NUM_CHANNELS 3 // current number of channels
00063 #define NUM_L_BINS 25 // # bins for L component of CIELab
00064 #define NUM_A_BINS 25 // # bins for a component of CIELab
00065 #define NUM_B_BINS 25 // # bins for b component of CIELab
00066 #define NUM_HISTOGRAM_DIMS 75 // current total number of bins
00067
00068 #define UNVISITED_REGION 0 // unvisited mean, just looked at
00069
00070 #define CENTER_REGION 1
00071 #define CENTER_CORE_REGION 2
00072 #define SURROUND_REGION 3
00073 #define UNASSIGNED_REGION 4
00074 #define OTHER_OBJECT_REGION 5
00075
00076 #define CLOSER_SIDE 1
00077 #define FAR_SIDE 2
00078
00079
00080
00081
00082
00083 SalientRegionSegmenter::SalientRegionSegmenter()
00084 :
00085 itsContourBoundaryDetector(new ContourBoundaryDetector())
00086 {
00087 itsWin.reset();
00088
00089
00090 float bg_smooth_sigma = 0.1;
00091 float cg_smooth_sigma = 0.05;
00092
00093 itsLKernel =
00094 gaussian<float>(1.0F, NUM_L_BINS*bg_smooth_sigma,
00095 int(3.0F*NUM_L_BINS*bg_smooth_sigma + 0.5F));
00096 itsAKernel =
00097 gaussian<float>(1.0F, NUM_A_BINS*cg_smooth_sigma,
00098 int(3.0F*NUM_A_BINS*cg_smooth_sigma + 0.5F));
00099 itsBKernel =
00100 gaussian<float>(1.0F, NUM_B_BINS*cg_smooth_sigma,
00101 int(3.0F*NUM_B_BINS*cg_smooth_sigma + 0.5F));
00102
00103 float suml = sum(itsLKernel); itsLKernel = itsLKernel/suml;
00104 float suma = sum(itsAKernel); itsAKernel = itsAKernel/suma;
00105 float sumb = sum(itsBKernel); itsBKernel = itsBKernel/sumb;
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 }
00133
00134
00135 SalientRegionSegmenter::~SalientRegionSegmenter()
00136 { }
00137
00138
00139 void SalientRegionSegmenter::setImage(Image<PixRGB<byte> > image)
00140 {
00141
00142 itsSalientPoints.clear();
00143
00144 itsImage = image;
00145
00146
00147 setImageFeatureHistogramValues();
00148
00149 uint w = itsImage.getWidth();
00150 uint h = itsImage.getHeight();
00151
00152 if(itsWin.is_invalid())
00153 itsWin.reset(new XWinManaged(Dims(4*w,2*h), 0, 0,
00154 "SalReg Segmenter"));
00155 else itsWin->setDims(Dims(4*w,2*h));
00156
00157
00158 computeBoundaryAndRegionInformation();
00159
00160
00161 uint hstep = BOUNDARY_STEP_SIZE/2;
00162 uint wG = (w-hstep)/BOUNDARY_STEP_SIZE;
00163 uint hG = (h-hstep)/BOUNDARY_STEP_SIZE;
00164 itsComputedHistograms =
00165 Image<rutz::shared_ptr<Histogram> >(wG, hG, ZEROS);
00166 }
00167
00168
00169 void SalientRegionSegmenter::setImageFeatureHistogramValues()
00170 {
00171
00172 Image<float> lImg;
00173 Image<float> aImg;
00174 Image<float> bImg;
00175 getNormalizedLAB(itsImage, lImg, aImg, bImg);
00176
00177
00178 itsImageHistogramEntries.clear();
00179 itsImageHistogramEntries.push_back(quantize_values(lImg, NUM_L_BINS));
00180 itsImageHistogramEntries.push_back(quantize_values(aImg, NUM_A_BINS));
00181 itsImageHistogramEntries.push_back(quantize_values(bImg, NUM_B_BINS));
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 }
00193
00194
00195 Image<int> SalientRegionSegmenter::quantize_values
00196 (Image<float> image, int num_bins, bool normalize)
00197 {
00198
00199
00200
00201
00202 uint w = itsImage.getWidth();
00203 uint h = itsImage.getHeight();
00204 Image<int> result(w,h,NO_INIT);
00205
00206 Image<float>::iterator iptr = image.beginw();
00207
00208 Image<int>::iterator aptr = result.beginw(), stop = result.endw();
00209 float nbins = num_bins;
00210 while(aptr != stop)
00211 {
00212 float in = *iptr++;
00213
00214
00215 int bin = int(in*nbins);
00216 if(bin == num_bins) bin = num_bins - 1;
00217 *aptr++ = bin;
00218
00219
00220 }
00221
00222 return result;
00223 }
00224
00225
00226 void SalientRegionSegmenter::computeBoundaryAndRegionInformation()
00227 {
00228 computeBoundaryInformation();
00229 computeRegionInformation();
00230
00231 displayBoundaryAndRegionInformation();
00232 }
00233
00234
00235 void SalientRegionSegmenter::computeBoundaryInformation()
00236 {
00237
00238 Timer timer(1000000); timer.reset();
00239 itsContourBoundaryDetector->computeContourBoundary(itsImage);
00240 LINFO("time: %f ms", timer.get()/1000.0);
00241
00242 itsContourBoundaries =
00243 itsContourBoundaryDetector->getContourBoundaries();
00244
00245 float maxVal = 0.0;
00246 for(uint i = 0; i < itsContourBoundaries.size(); i++)
00247 {
00248 rutz::shared_ptr<Contour> contour =
00249 itsContourBoundaries[i];
00250
00251
00252 uint cLen = contour->edgels.size();
00253 for(uint j = 0; j < cLen; j++)
00254 {
00255 float val = contour->edgels[j]->val;
00256 if(maxVal < val) maxVal = val;
00257 }
00258 }
00259
00260 itsMaximumEdgelStrength = maxVal;
00261 }
00262
00263
00264 void SalientRegionSegmenter::computeRegionInformation()
00265 {
00266
00267
00268
00269 float sigma = .5; uint k = 25; uint min_size = 20; int num_ccs;
00270
00271 itsInitialRegionImage =
00272 SuperPixelSegment
00273 (itsImage, sigma, k, min_size, num_ccs, &itsInitialRegions);
00274
00275 itsInitialRegionColorImage =
00276 SuperPixelDebugImage(itsInitialRegions, itsImage);
00277
00278 itsRegionAdjecencyList = getRegionAdjecencyList();
00279
00280 }
00281
00282
00283 std::vector<std::vector<uint> >
00284 SalientRegionSegmenter::getRegionAdjecencyList()
00285 {
00286 uint nRegions = itsInitialRegions.size();
00287 std::vector<std::vector<uint> > adjList(nRegions);
00288 for(uint i = 0; i < nRegions; i++)
00289 adjList[i] = std::vector<uint>();
00290
00291
00292
00293
00294
00295 for(uint i = 0; i < nRegions; i++)
00296 {
00297 for(uint j = 0; j < itsInitialRegions[i].size(); j++)
00298 {
00299 Point2D<int> pt = itsInitialRegions[i][j];
00300 uint label = i;
00301
00302 for(int di = -1; di <= 1; di++)
00303 {
00304 for(int dj = -1; dj <= -1; dj++)
00305 {
00306 Point2D<int> dpt(di,dj);
00307 Point2D<int> pt2 = pt + dpt;
00308 if(!(di == 0 && dj == 0) &&
00309 itsInitialRegionImage.coordsOk(pt2))
00310 {
00311
00312 uint label2 = itsInitialRegionImage.getVal(pt2);
00313
00314
00315
00316 if(label != label2)
00317 {
00318 bool in = false;
00319 for(uint l = 0; l < adjList[i].size(); l++)
00320 {
00321 if(adjList[i][l] == label2)
00322 { in = true; l = adjList[i].size(); }
00323 }
00324 if(!in) adjList[i].push_back(label2);
00325 }
00326 }
00327 }
00328 }
00329 }
00330 }
00331 return adjList;
00332 }
00333
00334
00335 void SalientRegionSegmenter::displayRegionAdjecencyList()
00336 {
00337
00338 Image<PixRGB<byte> > ima = itsImage;
00339
00340 Image<float> fIma(luminance(ima));
00341 Image<float> tempFIma = fIma;
00342 inplaceNormalize(tempFIma, 0.0f,255.0f);
00343 Image<byte> bIma(tempFIma);
00344
00345
00346 float mVal = 32;
00347 float bVal = 255 - mVal;
00348
00349 Image<byte> dImaR, dImaG, dImaB;
00350 getComponents(ima, dImaR, dImaG, dImaB);
00351 inplaceNormalize(dImaR, byte(0), byte(mVal));
00352 inplaceNormalize(dImaG, byte(0), byte(mVal));
00353 inplaceNormalize(dImaB, byte(0), byte(mVal));
00354 Image<PixRGB<byte> > dIma = makeRGB(dImaR,dImaG,dImaB);
00355
00356 uint w = ima.getWidth();
00357 uint h = ima.getHeight();
00358 Image<PixRGB<byte> > dispIma(4*w,2*h,ZEROS);
00359
00360 inplacePaste (dispIma, ima, Point2D<int>(0,0));
00361
00362 uint nRegions = itsInitialRegions.size();
00363 for(uint i = 0; i < nRegions; i++)
00364 {
00365 LINFO("region: %d (%d pix): has %d neighbors",
00366 i, int(itsInitialRegions[i].size()),
00367 int(itsRegionAdjecencyList[i].size()));
00368 Image<float> regionMap(w,h, ZEROS);
00369
00370 for(uint j = 0; j < itsInitialRegions[i].size(); j++)
00371 {
00372 Point2D<int> pt = itsInitialRegions[i][j];
00373 regionMap.setVal(pt, 1.0);
00374
00375
00376 }
00377
00378 for(uint j = 0; j < itsRegionAdjecencyList[i].size(); j++)
00379 {
00380 uint label = itsRegionAdjecencyList[i][j];
00381 LINFO(" [%3d] label: %d has: %d pixels",
00382 j, label, int(itsInitialRegions[label].size()));
00383 float randVal = rand()/(RAND_MAX+1.0);
00384 for(uint k = 0; k < itsInitialRegions[label].size(); k++)
00385 {
00386 Point2D<int> ptNeighbor = itsInitialRegions[label][k];
00387 regionMap.setVal(ptNeighbor, randVal);
00388
00389 }
00390 }
00391
00392 inplaceNormalize(regionMap, 0.0f,bVal);
00393 Image<byte> dBmapc(regionMap);
00394 Image<PixRGB<byte> > dBmap = toRGB(dBmapc);
00395
00396 inplacePaste
00397 (dispIma, Image<PixRGB<byte> >(dIma+dBmap), Point2D<int>(w,0));
00398
00399 itsWin->drawImage(dispIma, 0,0);
00400
00401 Raster::waitForKey();
00402 }
00403 }
00404
00405
00406
00407 void SalientRegionSegmenter::displayBoundaryAndRegionInformation()
00408 {
00409
00410 Image<PixRGB<byte> > ima = itsImage;
00411 uint w = ima.getWidth();
00412 uint h = ima.getHeight();
00413
00414 Image<float> fIma(luminance(ima));
00415 Image<float> tempFIma = fIma;
00416 inplaceNormalize(tempFIma, 0.0f,255.0f);
00417 Image<byte> bIma(tempFIma);
00418
00419
00420 float mVal = 32;
00421 float bVal = 255 - mVal;
00422 Image<byte> dImaR, dImaG, dImaB;
00423 getComponents(ima, dImaR, dImaG, dImaB);
00424 inplaceNormalize(dImaR, byte(0), byte(mVal));
00425 inplaceNormalize(dImaG, byte(0), byte(mVal));
00426 inplaceNormalize(dImaB, byte(0), byte(mVal));
00427 Image<PixRGB<byte> > dIma = makeRGB(dImaR,dImaG,dImaB);
00428
00429 Image<float> tboundaryMap =
00430 itsContourBoundaryDetector->getVarianceRidgeBoundaryMap();
00431 Image<float> boundaryMap =
00432 clampedDiff(tboundaryMap, Image<float>(w,h,ZEROS));
00433 inplaceNormalize(boundaryMap, 0.0f,bVal);
00434 Image<byte> dBmapc(boundaryMap);
00435 Image<PixRGB<byte> > tdBmap = toRGB(dBmapc);
00436 Image<PixRGB<byte> > dBmap(dIma+tdBmap);
00437
00438
00439
00440 Image<float> dBmapNMStemp =
00441 itsContourBoundaryDetector->getNmsBoundaryMap();
00442 inplaceNormalize(dBmapNMStemp, 0.0F, 255.0F);
00443 Image<PixRGB<byte> > dBmapNMS =
00444 toRGB(Image<byte>(dBmapNMStemp));
00445
00446
00447 Image<float> dCBEmapTemp =
00448 itsContourBoundaryDetector->getEdgelBoundaryMap();
00449 inplaceNormalize(dCBEmapTemp, 0.0F, bVal);
00450 Image<PixRGB<byte> > tdCBEmap =
00451 toRGB(Image<byte>(dCBEmapTemp));
00452 Image<PixRGB<byte> > dCBEmap(dIma+tdCBEmap);
00453
00454
00455 Image<PixRGB<byte> > dCBmapTemp =
00456 itsContourBoundaryDetector->getContourBoundaryMap();
00457 Image<PixRGB<byte> > dCBmap(dIma+dCBmapTemp);
00458
00459
00460
00461
00462
00463
00464 uint cl = 90; uint ct = 14; uint cr = 8;
00465 uint sl = cl - 4; uint st = ct - 4; uint sr = 16;
00466
00467
00468 drawRect(ima,
00469 Rectangle(Point2D<int>(cl, ct), Dims(cr, cr)),
00470 PixRGB<byte>(255,0,0));
00471 drawRect(ima,
00472 Rectangle(Point2D<int>(sl, st), Dims(sr, sr)),
00473 PixRGB<byte>(255,255,0));
00474
00475
00476
00477 drawRect(dBmap,
00478 Rectangle(Point2D<int>(cl, ct), Dims(cr, cr)),
00479 PixRGB<byte>(255,0,0));
00480 drawRect(dBmap,
00481 Rectangle(Point2D<int>(sl, st), Dims(sr, sr)),
00482 PixRGB<byte>(255,255,0));
00483
00484
00485
00486 drawRect(dBmapNMS,
00487 Rectangle(Point2D<int>(cl, ct), Dims(cr, cr)),
00488 PixRGB<byte>(255,0,0));
00489 drawRect(dBmapNMS,
00490 Rectangle(Point2D<int>(sl, st), Dims(sr, sr)),
00491 PixRGB<byte>(255,255,0));
00492
00493
00494
00495 drawRect(dCBEmap,
00496 Rectangle(Point2D<int>(cl, ct), Dims(cr, cr)),
00497 PixRGB<byte>(255,0,0));
00498 drawRect(dCBEmap,
00499 Rectangle(Point2D<int>(sl, st), Dims(sr, sr)),
00500 PixRGB<byte>(255,255,0));
00501
00502
00503
00504 drawRect(dCBmap,
00505 Rectangle(Point2D<int>(cl, ct), Dims(cr, cr)),
00506 PixRGB<byte>(255,0,0));
00507 drawRect(dCBmap,
00508 Rectangle(Point2D<int>(sl, st), Dims(sr, sr)),
00509 PixRGB<byte>(255,255,0));
00510
00511
00512
00513 Image<PixRGB<byte> > dispIma(4*w,2*h,ZEROS);
00514 inplacePaste(dispIma, ima, Point2D<int>( 0, 0));
00515 inplacePaste(dispIma, dBmap, Point2D<int>( w, 0));
00516 inplacePaste(dispIma, dBmapNMS, Point2D<int>( 0, h));
00517 inplacePaste(dispIma, dCBEmap, Point2D<int>( w, h));
00518 inplacePaste(dispIma, dCBmap, Point2D<int>(2*w, 0));
00519 inplacePaste(dispIma, itsInitialRegionColorImage, Point2D<int>(2*w, h));
00520
00521
00522
00523 itsWin->drawImage(dispIma, 0,0);
00524 Raster::waitForKey();
00525 }
00526
00527
00528 Image<float> SalientRegionSegmenter::getSalientRegion(Point2D<int> pt)
00529 {
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 pt = Point2D<int>(155,37);
00542 LINFO("\n\n\n\n\n hard coding salient location: %d %d "
00543 "TAKE IT OUT LATER!\n\n\n", pt.i, pt.j);
00544
00545
00546 uint hstep = BOUNDARY_STEP_SIZE/2;
00547 uint i = ((pt.i+hstep)/BOUNDARY_STEP_SIZE) * BOUNDARY_STEP_SIZE;
00548 uint j = ((pt.j+hstep)/BOUNDARY_STEP_SIZE) * BOUNDARY_STEP_SIZE;
00549 itsSalientPoints.push_back(Point2D<int>(i,j));
00550
00551 LINFO("adjusted point: %d %d", i,j);
00552
00553
00554 computeSalientRegion();
00555
00556 return itsSalientRegionImage;
00557 }
00558
00559
00560 void SalientRegionSegmenter::computeSalientRegion()
00561 {
00562
00563
00564
00565 uint w = itsImage.getWidth();
00566 uint h = itsImage.getHeight();
00567
00568 uint hstep = BOUNDARY_STEP_SIZE/2;
00569 uint wG = (w-hstep)/BOUNDARY_STEP_SIZE;
00570 uint hG = (h-hstep)/BOUNDARY_STEP_SIZE;
00571
00572 Point2D<int> currentSalPoint =
00573 itsSalientPoints[itsSalientPoints.size()-1];
00574 LINFO("START at salient point %d %d",
00575 currentSalPoint.i, currentSalPoint.j);
00576
00577 Point2D<int> currentSalPointGrid
00578 (currentSalPoint.i/BOUNDARY_STEP_SIZE,
00579 currentSalPoint.j/BOUNDARY_STEP_SIZE);
00580
00581
00582 Image<int> assignmentMap(wG, hG, ZEROS);
00583
00584
00585 for(uint i = 0; i < wG; i++)
00586 {
00587 assignmentMap.setVal(i,0, OTHER_OBJECT_REGION);
00588 assignmentMap.setVal(i,1, OTHER_OBJECT_REGION);
00589 }
00590 for(uint j = 0; j < hG; j++)
00591 {
00592 assignmentMap.setVal(0,j, OTHER_OBJECT_REGION);
00593 assignmentMap.setVal(1,j, OTHER_OBJECT_REGION);
00594 }
00595
00596 for(uint i = 0; i < wG; i++)
00597 {
00598 if(hG > 0)
00599 assignmentMap.setVal(i,hG-1, OTHER_OBJECT_REGION);
00600 if(hG > 1)
00601 assignmentMap.setVal(i,hG-2, OTHER_OBJECT_REGION);
00602 }
00603 for(uint j = 0; j < hG; j++)
00604 {
00605 if(wG > 0)
00606 assignmentMap.setVal(0,j, OTHER_OBJECT_REGION);
00607 if(wG > 1)
00608 assignmentMap.setVal(1,j, OTHER_OBJECT_REGION);
00609 }
00610
00611
00612
00613 std::vector<Point2D<int> > currentObjectLocations;
00614 std::vector<Point2D<int> > currentObjectCoreLocations;
00615 std::vector<Point2D<int> > currentBackgroundLocations;
00616 std::vector<Point2D<int> > currentUnassignedLocations;
00617
00618
00619 Image<int> regionAssignmentMap(w, h, ZEROS);
00620
00621
00622
00623 std::vector<int> currentObjectRegionList;
00624
00625 std::vector<int> currentBackgroundRegionList;
00626
00627
00628
00629 currentObjectCoreLocations.push_back(currentSalPointGrid);
00630
00631
00632
00633
00634
00635
00636 std::list<Segment> sortedSegments = fillSegmentQueue(currentSalPoint);
00637
00638
00639 Point2D<int> currPoint = currentSalPoint;
00640 Point2D<int> currPointGrid = currentSalPointGrid;
00641
00642 LINFO("START PT: %3d %3d --> %3d %3d",
00643 currPoint.i, currPoint.j, currPointGrid.i, currPointGrid.j);
00644
00645 std::vector<std::pair<Segment,Point2D<int> > > segmentPtCombo;
00646
00647
00648
00649 currentUnassignedLocations.push_back(currPointGrid);
00650 assignmentMap.setVal(currPointGrid, UNASSIGNED_REGION);
00651
00652
00653
00654 while(currentUnassignedLocations.size() != 0)
00655 {
00656
00657 filterSegments(sortedSegments);
00658 if(sortedSegments.size() == 0) break;
00659
00660
00661 Segment segment = sortedSegments.front();
00662 sortedSegments.pop_front();
00663
00664
00665 segmentPtCombo.push_back
00666 (std::pair<Segment,Point2D<int> >(segment, currPoint));
00667
00668
00669 Histogram hist1 = getHistogramDistribution(currPoint);
00670
00671
00672
00673 std::vector<Point2D<int> > pts2;
00674 std::vector<Point2D<int> > pts3;
00675 getSegmentPointDistributions(segment, currPoint, pts2, pts3);
00676 Histogram hist2 = getHistogramDistribution(pts2);
00677 Histogram hist3 = getHistogramDistribution(pts3);
00678
00679
00680 float threshDiff = hist1.getChiSqDiff(hist2);
00681 LINFO("THRESH Diff: %f", threshDiff);
00682
00683 LINFO("{%3d} %10.3f, %10.3f, %10.3f, %10.3f, %10.3f) = %10.3f",
00684 segment.orgIndex,
00685 segment.lenVal, segment.simVal, segment.strVal,
00686 segment.ratVal, segment.disVal, segment.pVal );
00687
00688
00689
00690 int index = segment.segStartIndex + MINIMUM_CONTOUR_LENGTH/2;
00691 rutz::shared_ptr<Contour> contour =
00692 itsContourBoundaries[segment.contourIndex];
00693 rutz::shared_ptr<Edgel> edgel = contour->edgels[index];
00694
00695 Point2D<int> segCenterPointGrid
00696 ((edgel->pt.i+hstep)/BOUNDARY_STEP_SIZE,
00697 (edgel->pt.j+hstep)/BOUNDARY_STEP_SIZE );
00698
00699 std::vector<Point2D<int> > points =
00700 getLine(currPointGrid, segCenterPointGrid);
00701
00702 LINFO("segment points");
00703 for(uint i = segment.segStartIndex; i <= segment.segEndIndex; i++)
00704 {
00705 rutz::shared_ptr<Edgel> tedgel = contour->edgels[i];
00706 Point2D<int> tptGrid
00707 ((tedgel->pt.i+hstep)/BOUNDARY_STEP_SIZE,
00708 (tedgel->pt.j+hstep)/BOUNDARY_STEP_SIZE );
00709
00710 LINFO("[<<%3d>>] %d %d --> %d %d",
00711 i, tptGrid.i, tptGrid.j,
00712 tedgel->pt.i,tedgel->pt.j);
00713 }
00714
00715 LINFO("LINE: %3d %3d to %3d %3d",
00716 currPointGrid.i, currPointGrid.j,
00717 segCenterPointGrid.i, segCenterPointGrid.j);
00718 for(uint i = 0; i < points.size(); i++)
00719 {
00720 LINFO("[%3d]: %3d %3d", i, points[i].i, points[i].j);
00721 }
00722
00723
00724 Image<bool> isComparedWith(wG, hG, ZEROS);
00725 for(uint i = 0; i < points.size(); i++)
00726 {
00727 Point2D<int> startPt = points[i];
00728 LINFO("current starting point: %3d %3d", startPt.i, startPt.j);
00729
00730 std::vector<Point2D<int> >::iterator culItr =
00731 currentUnassignedLocations.begin();
00732
00733 if(assignmentMap.getVal(startPt) == UNVISITED_REGION)
00734 {
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 culItr = currentUnassignedLocations.begin();
00746 currentUnassignedLocations.insert(culItr, startPt);
00747
00748 assignmentMap.setVal(startPt, UNASSIGNED_REGION);
00749 }
00750 else LINFO("skip adding starting point -- already visited");
00751 Raster::waitForKey();
00752
00753
00754 uint currIndex = 0;
00755
00756
00757
00758 while(currIndex < currentUnassignedLocations.size())
00759 {
00760
00761 Point2D<int> ptGrid = currentUnassignedLocations[currIndex];
00762 Point2D<int> pt(ptGrid.i*BOUNDARY_STEP_SIZE,
00763 ptGrid.j*BOUNDARY_STEP_SIZE);
00764
00765 LINFO("curr pt to check: %3d %3d --> %3d %3d",
00766 ptGrid.i, ptGrid.j, pt.i, pt.j);
00767
00768
00769 if(!isComparedWith.getVal(ptGrid))
00770 {
00771 LINFO("was NOT compared with yet");
00772
00773
00774
00775 Histogram thist = getHistogramDistribution(pt);
00776 float diff = hist1.getChiSqDiff(thist);
00777 LINFO("difference:(%3d %3d) & (%3d %3d): %f",
00778 currPoint.i, currPoint.j, pt.i, pt.j, diff);
00779
00780
00781 if(diff < threshDiff)
00782 {
00783 LINFO("pass %d", currIndex);
00784
00785
00786 currentObjectLocations.push_back(ptGrid);
00787 assignmentMap.setVal(ptGrid, CENTER_REGION);
00788
00789
00790 uint bSize = currentUnassignedLocations.size();
00791 addUnvisitedNeighbors
00792 (currentUnassignedLocations, ptGrid,
00793 assignmentMap);
00794 uint aSize = currentUnassignedLocations.size();
00795 uint addN = aSize - bSize;
00796
00797
00798 culItr = currentUnassignedLocations.begin();
00799 currentUnassignedLocations.erase(culItr+currIndex+addN);
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 currIndex = 0;
00811
00812
00813 displayGrowMap(assignmentMap, currPoint,
00814 currentObjectLocations,
00815 currentObjectCoreLocations,
00816 currentBackgroundLocations,
00817 currentUnassignedLocations,
00818 isComparedWith, segment);
00819 }
00820 else
00821 {
00822 LINFO("didn't pass: %d", currIndex);
00823
00824
00825 currIndex++;
00826 }
00827
00828
00829 isComparedWith.setVal(ptGrid, true);
00830 }
00831
00832 else
00833 {
00834 LINFO("already checked: %d", currIndex);
00835
00836 currIndex++;
00837 }
00838 }
00839 }
00840
00841 LINFO("Done with segment {%3d}", segment.orgIndex);
00842 Raster::waitForKey();
00843
00844
00845 assignRegionsAroundSegment
00846 (segment, pts2, pts3,
00847 assignmentMap,
00848 currentObjectLocations,
00849 currentBackgroundLocations,
00850 currentUnassignedLocations,
00851 regionAssignmentMap,
00852 currentObjectRegionList,
00853 currentBackgroundRegionList);
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 LINFO("after the boundary assignment");
00868 displayGrowMap(assignmentMap, currPoint,
00869 currentObjectLocations,
00870 currentObjectCoreLocations,
00871 currentBackgroundLocations,
00872 currentUnassignedLocations,
00873 isComparedWith, segment);
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 }
00910
00911 Raster::waitForKey();
00912 }
00913
00914
00915 std::list<Segment> SalientRegionSegmenter::fillSegmentQueue
00916 (Point2D<int> pt)
00917 {
00918 std::list<Segment> sortedSegments;
00919
00920
00921 int index = 0;
00922 for(uint i = 0; i < itsContourBoundaries.size(); i++)
00923 {
00924 rutz::shared_ptr<Contour> contour =
00925 itsContourBoundaries[i];
00926
00927 uint cLen = contour->edgels.size();
00928
00929
00930
00931
00932 if(cLen < MINIMUM_CONTOUR_LENGTH) continue;
00933
00934
00935 float step = float(MINIMUM_CONTOUR_LENGTH)/2.0F;
00936 uint numSegments = uint(floor(float(cLen)/step));
00937 if((cLen%MINIMUM_CONTOUR_LENGTH) == 0) numSegments--;
00938 LINFO("Contour[%3d]: %3d: numSegments: %d",
00939 i, cLen, numSegments);
00940
00941 for(uint j = 0; j < numSegments; j++)
00942 {
00943 uint start = uint(j*step);
00944 uint end = start + MINIMUM_CONTOUR_LENGTH - 1;
00945
00946 if(end >= cLen)
00947 {
00948 end = cLen - 1;
00949 start = end + 1 - MINIMUM_CONTOUR_LENGTH;
00950 }
00951
00952 Segment segment(index, i, start, end);
00953
00954 LINFO("[i: %3d c: %3d s: %3d e: %3d]", index, i, start, end);
00955
00956 setPriority(segment, pt);
00957 sortedSegments.push_back(segment);
00958
00959 index++;
00960 }
00961 }
00962
00963 Raster::waitForKey();
00964
00965
00966 LINFO("Before Sorting");
00967 std::list<Segment>::iterator
00968 itr = sortedSegments.begin(),
00969 stop = sortedSegments.end();
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 sortedSegments.sort();
00984
00985 LINFO("After Sorting");
00986
00987 itr = sortedSegments.begin();
00988 stop = sortedSegments.end();
00989 while (itr != stop)
00990 {
00991 LINFO("[%3d] %6.3f*%10.3f + %6.3f*%10.3f + %6.3f*%10.3f + "
00992 "%6.3f*%10.3f + %6.3f*%10.3f = %10.3f", (*itr).orgIndex,
00993 LEN_WEIGHT, (*itr).lenVal,
00994 SIM_WEIGHT, (*itr).simVal,
00995 STR_WEIGHT, (*itr).strVal,
00996 RAT_WEIGHT, (*itr).ratVal,
00997 DIS_WEIGHT, (*itr).disVal, (*itr).pVal);
00998 itr++;
00999 }
01000 Raster::waitForKey();
01001
01002 return sortedSegments;
01003 }
01004
01005
01006
01007 void SalientRegionSegmenter::setPriority
01008 (Segment &segment, Point2D<int> pt)
01009 {
01010 uint w = itsImage.getWidth();
01011 uint h = itsImage.getHeight();
01012 float diag = pow(w*w + h*h, 0.5);
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 rutz::shared_ptr<Contour> contour =
01024 itsContourBoundaries[segment.contourIndex];
01025 uint cLen = contour->edgels.size();
01026
01027
01028 float tempCLen = float(cLen);
01029 float maxLen = float(MINIMUM_CONTOUR_LENGTH * 3);
01030 if(tempCLen > maxLen) tempCLen = maxLen;
01031 float lenVal = tempCLen/maxLen;
01032 segment.lenVal = lenVal;
01033
01034 LINFO("1. clen: %d --> lenVal: %f", cLen, lenVal);
01035
01036
01037 Histogram hist1 = getHistogramDistribution(pt);
01038 std::vector<Point2D<int> > pts2;
01039 std::vector<Point2D<int> > pts3;
01040 getSegmentPointDistributions(segment, pt, pts2, pts3);
01041
01042 Histogram hist2 = getHistogramDistribution(pts2);
01043 Histogram hist3 = getHistogramDistribution(pts3);
01044 float diff12 = hist1.getChiSqDiff(hist2);
01045
01046 float tempDiff = diff12;
01047 if(tempDiff > 1.0) tempDiff = 1.0;
01048 float simVal = 1.0F - tempDiff;
01049 segment.simVal = simVal;
01050
01051 LINFO("2. diff12: %f --> simVal: %f", diff12, simVal);
01052
01053
01054 float val = 0.0;
01055 uint start = segment.segStartIndex;
01056 uint end = segment.segEndIndex;
01057 for(uint i = start; i <= end; i++)
01058 {
01059 val += contour->edgels[i]->val;
01060 }
01061 val /= float(end - start + 1);
01062 float maxStr = .5 * itsMaximumEdgelStrength;
01063 float strVal = val/maxStr; if(strVal > 1.0F) strVal = 1.0;
01064 segment.strVal = strVal;
01065
01066 LINFO("3. strength of boundary: %f / %f = strVal: %f",
01067 val, itsMaximumEdgelStrength, strVal);
01068
01069
01070 float diff13 = hist1.getChiSqDiff(hist3);
01071 float ratio = MAX_FAR_TO_NEAR_RATIO;
01072 if(diff12 > 0.0) ratio = diff13/diff12;
01073 float nratio = MAX_FAR_TO_NEAR_RATIO;
01074 if(ratio < MAX_FAR_TO_NEAR_RATIO) nratio = ratio;
01075 float ratVal = nratio/MAX_FAR_TO_NEAR_RATIO;
01076 segment.ratVal = ratVal;
01077
01078 LINFO("4. ratio in&out: %f/%f = %f --> ratVal: %f",
01079 diff13, diff12, ratio, ratVal);
01080
01081
01082
01083 int index = segment.segStartIndex + MINIMUM_CONTOUR_LENGTH/2;
01084 float dist = pt.distance(contour->edgels[index]->pt);
01085 float mdist = MAX_DISTANCE * diag;
01086 float disVal = 1.0;
01087 if(dist > mdist) disVal = 1.0F - (dist - mdist)/(diag - mdist);
01088 segment.disVal = disVal;
01089
01090 LINFO("5. distance: dist: %f/mdist: %f --> disVal: %f",
01091 dist, mdist, disVal);
01092
01093 segment.pVal =
01094 LEN_WEIGHT * lenVal +
01095 SIM_WEIGHT * simVal +
01096 STR_WEIGHT * strVal +
01097 RAT_WEIGHT * ratVal +
01098 DIS_WEIGHT * disVal;
01099
01100 LINFO("Total: %f", segment.pVal);
01101
01102 }
01103
01104
01105 Histogram SalientRegionSegmenter::getHistogramDistribution
01106 (Point2D<int> pt)
01107 {
01108
01109
01110 Histogram lHist(NUM_L_BINS);
01111 Histogram aHist(NUM_A_BINS);
01112 Histogram bHist(NUM_L_BINS);
01113
01114 int rad = NEIGHBORHOOD_RADIUS;
01115 int numPoints = 0;
01116 for(int i = -rad; i <= rad; i++)
01117 for(int j = -rad; j <= rad; j++)
01118 {
01119 bool isWithinCircle = ((i*i+j*j) <= (rad*rad));
01120
01121 Point2D<int> pt2 = pt + Point2D<int>(i,j);
01122 if(itsImage.coordsOk(pt2) && isWithinCircle)
01123 {
01124
01125 int l_val = itsImageHistogramEntries[0].getVal(pt2);
01126 lHist.addValue(l_val, 1.0F);
01127
01128
01129 int a_val = itsImageHistogramEntries[1].getVal(pt2);
01130 aHist.addValue(a_val, 1.0F);
01131
01132
01133 int b_val = itsImageHistogramEntries[2].getVal(pt2);
01134 bHist.addValue(b_val, 1.0F);
01135
01136 numPoints++;
01137 }
01138 }
01139
01140
01141
01142
01143
01144
01145 lHist.smooth(itsLKernel);
01146 aHist.smooth(itsAKernel);
01147 bHist.smooth(itsBKernel);
01148
01149
01150 std::vector<Histogram> histograms;
01151 histograms.push_back(lHist);
01152 histograms.push_back(aHist);
01153 histograms.push_back(bHist);
01154 Histogram histogram(histograms);
01155
01156
01157 histogram.divide(numPoints);
01158
01159 return histogram;
01160 }
01161
01162
01163 Histogram SalientRegionSegmenter::getHistogramDistribution
01164 (std::vector<Point2D<int> > pts)
01165 {
01166 Histogram lHist(NUM_L_BINS);
01167 Histogram aHist(NUM_A_BINS);
01168 Histogram bHist(NUM_L_BINS);
01169
01170 int numPoints = 0;
01171 for(uint i = 0; i < pts.size(); i++)
01172 {
01173 Point2D<int> pt = pts[i];
01174 if(itsImage.coordsOk(pt))
01175 {
01176
01177 int l_val = itsImageHistogramEntries[0].getVal(pt);
01178 lHist.addValue(l_val, 1.0F);
01179
01180
01181 int a_val = itsImageHistogramEntries[1].getVal(pt);
01182 aHist.addValue(a_val, 1.0F);
01183
01184
01185 int b_val = itsImageHistogramEntries[2].getVal(pt);
01186 bHist.addValue(b_val, 1.0F);
01187
01188 numPoints++;
01189 }
01190 }
01191
01192 LINFO("num points: %d", numPoints);
01193
01194
01195
01196
01197
01198 lHist.smooth(itsLKernel);
01199 aHist.smooth(itsAKernel);
01200 bHist.smooth(itsBKernel);
01201
01202
01203 std::vector<Histogram> histograms;
01204 histograms.push_back(lHist);
01205 histograms.push_back(aHist);
01206 histograms.push_back(bHist);
01207 Histogram histogram(histograms);
01208
01209
01210 histogram.divide(numPoints);
01211
01212 return histogram;
01213 }
01214
01215
01216 void SalientRegionSegmenter::getSegmentPointDistributions
01217 (Segment segment, Point2D<int> pt,
01218 std::vector<Point2D<int> > &pts1, std::vector<Point2D<int> > &pts2)
01219 {
01220
01221 uint start = segment.segStartIndex;
01222 uint end = segment.segEndIndex;
01223
01224 rutz::shared_ptr<Contour> contour =
01225 itsContourBoundaries[segment.contourIndex];
01226
01227 rutz::shared_ptr<Edgel> edgels = contour->edgels[start];
01228 rutz::shared_ptr<Edgel> edgele = contour->edgels[end ];
01229
01230 uint ainds = edgels->angleIndex;
01231 float bainds =
01232 fmod((ainds+(NUM_RIDGE_DIRECTIONS/2)),NUM_RIDGE_DIRECTIONS);
01233 uint ainde = edgele->angleIndex;
01234 float bainde =
01235 fmod((ainde+(NUM_RIDGE_DIRECTIONS/2)),NUM_RIDGE_DIRECTIONS);
01236
01237 int step = BOUNDARY_STEP_SIZE;
01238 int hstep = step/2;
01239 float dxs = cos(bainds * M_PI/4.0) * hstep;
01240 float dys = sin(bainds * M_PI/4.0) * hstep;
01241
01242 float dxe = cos(bainde * M_PI/4.0) * hstep;
01243 float dye = sin(bainde * M_PI/4.0) * hstep;
01244
01245 Point2D<float> p1 = edgels->pt + Point2D<float>(-dxs-.5, -dys-.5);
01246 Point2D<float> p2 = edgele->pt + Point2D<float>( dxe+.5, dye+.5);
01247
01248
01249 float ang = atan2(p2.j-p1.j, p2.i-p1.i);
01250
01251
01252
01253
01254 float cAng = M_PI/2.0F - ang;
01255 if(ang < 0.0F && ang > M_PI)
01256 { LFATAL("out of Bounds Angle -- Fix it"); }
01257
01258 if(cAng == 0.0F)
01259 {
01260 LINFO("Deal with ZERO corrected angle");
01261 Raster::waitForKey();
01262 }
01263
01264 float cCAng = cos(cAng);
01265 float sCAng = sin(cAng);
01266
01267
01268 Point2D<float> mid((p1.i+p2.i)/2.0, (p1.j+p2.j)/2.0);
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 float tbR = 0.0; float bbR = 0.0;
01283 float lbR = 0.0; float rbR = 0.0;
01284 std::vector<Point2D<float> > sPt;
01285 std::vector<Point2D<float> > ePt;
01286 std::vector<Point2D<float> > srPt;
01287 std::vector<Point2D<float> > erPt;
01288 std::vector<Point2D<float> > mrPt;
01289 for(uint k = start; k <= end; k++)
01290 {
01291 Point2D<int> pt = contour->edgels[k]->pt;
01292 float i = pt.i - mid.i;
01293 float j = pt.j - mid.j;
01294 float iR = i*cCAng - j*sCAng;
01295 float jR = i*sCAng + j*cCAng;
01296
01297 uint aind = contour->edgels[k]->angleIndex;
01298 float baind =
01299 fmod((aind+(NUM_RIDGE_DIRECTIONS/2)),NUM_RIDGE_DIRECTIONS);
01300 float dx = cos(baind * M_PI/4.0) * hstep;
01301 float dy = sin(baind * M_PI/4.0) * hstep;
01302
01303 Point2D<float> ps = pt + Point2D<float>(-dx-.5, -dy-.5);
01304 Point2D<float> pe = pt + Point2D<float>( dx+.5, dy+.5);
01305
01306 float si = ps.i - mid.i;
01307 float sj = ps.j - mid.j;
01308 float siR = si*cCAng - sj*sCAng;
01309 float sjR = si*sCAng + sj*cCAng;
01310
01311 float ei = pe.i - mid.i;
01312 float ej = pe.j - mid.j;
01313 float eiR = ei*cCAng - ej*sCAng;
01314 float ejR = ei*sCAng + ej*cCAng;
01315
01316 sPt.push_back(ps);
01317 ePt.push_back(pe);
01318 srPt.push_back(Point2D<float>(siR,sjR));
01319 erPt.push_back(Point2D<float>(eiR,ejR));
01320 mrPt.push_back(Point2D<float>( iR, jR));
01321
01322
01323 if(k == start)
01324 {
01325 tbR = sjR;
01326 bbR = sjR;
01327 lbR = siR;
01328 rbR = siR;
01329 }
01330
01331 if(tbR > sjR) tbR = sjR;
01332 if(tbR > ejR) tbR = ejR;
01333
01334 if(bbR < sjR) bbR = sjR;
01335 if(bbR < ejR) bbR = ejR;
01336
01337 if(lbR > siR) lbR = siR;
01338 if(lbR > eiR) lbR = eiR;
01339
01340 if(rbR < siR) rbR = siR;
01341 if(rbR < eiR) rbR = eiR;
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351 }
01352
01353
01354
01355
01356 float areaL = 0; float areaR = 0;
01357 float w = rbR - lbR;
01358 float h = bbR - tbR;
01359 if(w > 0.0F && h > 0.0F)
01360 {
01361 for(uint k = start; k <= end; k++)
01362 {
01363 int i = k-start;
01364
01365
01366
01367 float tl = rbR - srPt[i].i;
01368 float bl = rbR - erPt[i].i;
01369
01370 float h = erPt[i].j - srPt[i].j;
01371
01372 float trapArea = (tl+bl)*h/2.0F;
01373 float boxArea = w*h;
01374 areaL += (boxArea-trapArea);
01375 areaR += trapArea;
01376
01377
01378
01379
01380
01381
01382
01383
01384 }
01385 }
01386
01387
01388
01389
01390 uint nrad = NEIGHBORHOOD_RADIUS;
01391 float minArea = nrad * nrad * M_PI;
01392 float extL = 0.0; float extR = 0.0;
01393
01394
01395
01396 if(areaL < minArea)
01397 {
01398 extL = lbR - (minArea - areaL)/h;
01399 }
01400
01401 if(areaR < minArea)
01402 {
01403 extR = rbR + (minArea - areaR)/h;
01404 }
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415 int pti = pt.i - mid.i;
01416 int ptj = pt.j - mid.j;
01417 float ptiR = pti*cCAng - ptj*sCAng;
01418
01419 float isLeft = true; if(ptiR > 0.0) isLeft = false;
01420
01421
01422
01423 uint finalW = extR-extL;
01424 uint finalH = h;
01425 uint maxDim = finalW;
01426 if(finalH > finalW) maxDim = finalH;
01427 Image<byte> temp1(maxDim*2, maxDim*2, ZEROS);
01428 Image<byte> temp2(maxDim*2, maxDim*2, ZEROS);
01429
01430
01431
01432 for(uint k = start; k <= end; k++)
01433 {
01434 uint ind = k - start;
01435
01436 float t = srPt[ind].j; float b = erPt[ind].j;
01437 float h = b - t;
01438
01439 float tH = srPt[ind].i; float bH = erPt[ind].i;
01440 float w = bH - tH;
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450 for(int j = int(t); j <= int(b + .5F); j++)
01451 {
01452
01453 float div = (w/h*(j - b)) + tH;
01454 if(w < 0.0F) div = (w/h*(j - t)) + tH;
01455
01456 float leftE = extL+maxDim;
01457 float rightE = extR+maxDim;
01458
01459
01460
01461
01462
01463 uint jShift = j + maxDim;
01464 for(int i = int(leftE); i <= int(rightE+.5F); i++)
01465 {
01466 if(i < (div+maxDim))
01467 {
01468 if(isLeft) temp1.setVal(i,jShift, 128);
01469 else temp2.setVal(i,jShift, 128);
01470 }
01471 else
01472 {
01473 if(isLeft) temp2.setVal(i,jShift, 128);
01474 else temp1.setVal(i,jShift, 128);
01475 }
01476
01477
01478
01479 }
01480
01481
01482
01483 }
01484
01485
01486
01487 }
01488
01489
01490
01491
01492
01493
01494 Image<byte> temp1R = rotate(temp1, maxDim, maxDim, -cAng);
01495 Image<byte> temp2R = rotate(temp2, maxDim, maxDim, -cAng);
01496
01497
01498
01499
01500 int tw = temp1.getWidth();
01501 int th = temp1.getHeight();
01502 for(int i = 0; i < tw; i++)
01503 for(int j = 0; j < th; j++)
01504 {
01505 if(temp1R.getVal(i,j) > 64)
01506 {
01507 Point2D<int> pt(i+int(mid.i)-maxDim,
01508 j+int(mid.j)-maxDim );
01509 pts1.push_back(pt);
01510
01511
01512 }
01513
01514 if(temp2R.getVal(i,j) > 64)
01515 {
01516 Point2D<int> pt(i+int(mid.i)-maxDim,
01517 j+int(mid.j)-maxDim );
01518 pts2.push_back(pt);
01519
01520
01521 }
01522 }
01523
01524
01525 }
01526
01527
01528 void SalientRegionSegmenter::filterSegments(std::list<Segment> &segments)
01529 {
01530
01531
01532
01533
01534 }
01535
01536
01537 void SalientRegionSegmenter::addUnvisitedNeighbors
01538 (std::vector<Point2D<int> > ¤tUnassignedLocations,
01539 Point2D<int> currPointGrid, Image<int> &assignmentMap)
01540 {
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559 for(int j = 1; j >= -1; j--)
01560 for(int i = 1; i >= -1; i--)
01561 if(!(i == 0 && j== 0))
01562 {
01563 Point2D<int> pt(currPointGrid.i+i, currPointGrid.j+j);
01564
01565
01566 if(assignmentMap.coordsOk(pt) &&
01567 assignmentMap.getVal(pt) == UNVISITED_REGION)
01568 {
01569 LINFO("pt(%3d %3d): %d", pt.i,pt.j,
01570 assignmentMap.getVal(pt));
01571
01572 std::vector<Point2D<int> >::iterator itr =
01573 currentUnassignedLocations.begin();
01574 currentUnassignedLocations.insert(itr, pt);
01575
01576 assignmentMap.setVal(pt, UNASSIGNED_REGION);
01577 }
01578 }
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 }
01590
01591
01592 std::vector<Point2D<int> > SalientRegionSegmenter::getLine
01593 (Point2D<int> p1, Point2D<int> p2)
01594 {
01595 std::vector<Point2D<int> > points;
01596
01597
01598
01599 int dx = p2.i - p1.i, ax = abs(dx) << 1, sx = signOf(dx);
01600 int dy = p2.j - p1.j, ay = abs(dy) << 1, sy = signOf(dy);
01601 int x = p1.i, y = p1.j;
01602
01603 const int w = itsImage.getWidth();
01604 const int h = itsImage.getHeight();
01605
01606 if (ax > ay)
01607 {
01608 int d = ay - (ax >> 1);
01609 for (;;)
01610 {
01611
01612 if (x >= 0 && x < w && y >= 0 && y < h)
01613 points.push_back(Point2D<int>(x,y));
01614
01615 if (x == p2.i) return points;
01616 if (d >= 0) { y += sy; d -= ax; }
01617 x += sx; d += ay;
01618 }
01619 }
01620 else
01621 {
01622 int d = ax - (ay >> 1);
01623 for (;;)
01624 {
01625
01626 if (x >= 0 && x < w && y >= 0 && y < h)
01627 points.push_back(Point2D<int>(x,y));
01628
01629 if (y == p2.j) return points;
01630 if (d >= 0) { x += sx; d -= ay; }
01631 y += sy; d += ax;
01632 }
01633 }
01634
01635 return points;
01636 }
01637
01638
01639 void SalientRegionSegmenter::assignRegionsAroundSegment
01640 (Segment segment,
01641 std::vector<Point2D<int> > pts2,
01642 std::vector<Point2D<int> > pts3,
01643 Image<int> &assignmentMap,
01644 std::vector<Point2D<int> > ¤tObjectLocations,
01645 std::vector<Point2D<int> > ¤tBackgroundLocations,
01646 std::vector<Point2D<int> > ¤tUnassignedLocations,
01647 Image<int> ®ionAssignmentMap,
01648 std::vector<int> ¤tObjectRegionList,
01649 std::vector<int> ¤tBackgroundRegionList)
01650 {
01651 uint w = itsImage.getWidth();
01652 uint h = itsImage.getHeight();
01653
01654 uint hstep = BOUNDARY_STEP_SIZE/2;
01655
01656
01657
01658 Image<int> image(w,h, ZEROS);
01659 for(uint i = 0; i < pts2.size(); i++)
01660 {
01661 if(image.coordsOk(pts2[i]))
01662 image.setVal(pts2[i], CLOSER_SIDE);
01663 }
01664 for(uint i = 0; i < pts3.size(); i++)
01665 {
01666 if(image.coordsOk(pts3[i]))
01667 image.setVal(pts3[i], FAR_SIDE);
01668 }
01669 std::vector<std::vector<Point2D<int> > >
01670 neighbor(NUM_RIDGE_DIRECTIONS);
01671
01672 for(uint k = 0; k < NUM_RIDGE_DIRECTIONS; k++)
01673 {
01674 neighbor[k] = std::vector<Point2D<int> >();
01675
01676 if(k == 0)
01677 {
01678 neighbor[k].push_back(Point2D<int>( 1, 0));
01679 neighbor[k].push_back(Point2D<int>(-1, 0));
01680 }
01681 else if(k == 1)
01682 {
01683 neighbor[k].push_back(Point2D<int>(-1, -1));
01684 neighbor[k].push_back(Point2D<int>( 0, -1));
01685 neighbor[k].push_back(Point2D<int>(-1, 0));
01686 neighbor[k].push_back(Point2D<int>( 1, 0));
01687 neighbor[k].push_back(Point2D<int>( 0, 1));
01688 neighbor[k].push_back(Point2D<int>( 1, 1));
01689 }
01690 else if(k == 2)
01691 {
01692 neighbor[k].push_back(Point2D<int>( 0, 1));
01693 neighbor[k].push_back(Point2D<int>( 0, -1));
01694 }
01695 else if(k == 3)
01696 {
01697 neighbor[k].push_back(Point2D<int>( 0, -1));
01698 neighbor[k].push_back(Point2D<int>( 1, -1));
01699 neighbor[k].push_back(Point2D<int>(-1, 0));
01700 neighbor[k].push_back(Point2D<int>( 1, 0));
01701 neighbor[k].push_back(Point2D<int>(-1, 1));
01702 neighbor[k].push_back(Point2D<int>( 0, 1));
01703 }
01704 }
01705
01706
01707 for(uint e = segment.segStartIndex; e <= segment.segEndIndex; e++)
01708 {
01709 rutz::shared_ptr<Contour> contour =
01710 itsContourBoundaries[segment.contourIndex];
01711 rutz::shared_ptr<Edgel> edgel = contour->edgels[e];
01712 Point2D<int> pt = edgel->pt;
01713 Point2D<int> ptGrid
01714 ((pt.i+hstep)/BOUNDARY_STEP_SIZE,
01715 (pt.j+hstep)/BOUNDARY_STEP_SIZE );
01716 LINFO("[[[%3d]]] %d %d --> %d %d", e, pt.i, pt.j, ptGrid.i, ptGrid.j);
01717
01718 uint label = assignmentMap.getVal(ptGrid);
01719
01720
01721 if(label == CENTER_REGION) LINFO(" C_REGION : do nothing");
01722 if(label == SURROUND_REGION) LINFO(" S_REGION : do nothing");
01723 if(label == OTHER_OBJECT_REGION) LINFO("OO_REGION : do nothing");
01724
01725 if(label == UNVISITED_REGION)
01726 {
01727
01728 currentBackgroundLocations.push_back(ptGrid);
01729 assignmentMap.setVal(ptGrid, SURROUND_REGION);
01730
01731 LINFO("UNVISITED adding %3d %3d to the background",
01732 ptGrid.i, ptGrid.j);
01733 }
01734
01735 if(label == UNASSIGNED_REGION)
01736 {
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 uint pos = 0;
01759 for(uint i = 0; i < currentUnassignedLocations.size(); i++)
01760 if(ptGrid == currentUnassignedLocations[i])
01761 { pos = i; i = currentUnassignedLocations.size(); }
01762
01763
01764 std::vector<Point2D<int> >::iterator itr =
01765 currentUnassignedLocations.begin();
01766 currentUnassignedLocations.erase(itr+pos);
01767
01768
01769 currentBackgroundLocations.push_back(ptGrid);
01770 assignmentMap.setVal(ptGrid, SURROUND_REGION);
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792 }
01793 }
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815 for(uint e = segment.segStartIndex; e <= segment.segEndIndex; e++)
01816 {
01817 rutz::shared_ptr<Contour> contour =
01818 itsContourBoundaries[segment.contourIndex];
01819 rutz::shared_ptr<Edgel> edgel = contour->edgels[e];
01820 Point2D<int> pt = edgel->pt;
01821 Point2D<int> ptGrid
01822 ((pt.i+hstep)/BOUNDARY_STEP_SIZE,
01823 (pt.j+hstep)/BOUNDARY_STEP_SIZE );
01824
01825 uint dir = edgel->angleIndex;
01826
01827 LINFO("[<<%3d>>] %d %d --> %d %d (%d)",
01828 e, pt.i, pt.j, ptGrid.i, ptGrid.j, dir);
01829
01830
01831 for(uint i = 0; i < neighbor[dir].size(); i++)
01832 {
01833 Point2D<int> ptGrid2 = ptGrid + neighbor[dir][i];
01834 Point2D<int> pt2(ptGrid2.i*BOUNDARY_STEP_SIZE,
01835 ptGrid2.j*BOUNDARY_STEP_SIZE );
01836
01837 LINFO(" N[%3d]: %d %d --> %d %d",
01838 i, ptGrid2.i, ptGrid2.j, pt2.i, pt2.j);
01839
01840 if(!assignmentMap.coordsOk(ptGrid2))
01841 {
01842 LINFO("out of bounds"); continue;
01843 }
01844
01845 uint label2 = assignmentMap.getVal(ptGrid2);
01846 LINFO("LABEL2: %d", label2);
01847
01848
01849 if(label2 == CENTER_REGION) LINFO(" C_REGION : do nothing");
01850 if(label2 == SURROUND_REGION) LINFO(" S_REGION : do nothing");
01851 if(label2 == OTHER_OBJECT_REGION) LINFO("OO_REGION : do nothing");
01852
01853 if(label2 == UNVISITED_REGION)
01854 {
01855
01856 int side = image.getVal(pt2);
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873 if(side == CLOSER_SIDE)
01874 {
01875
01876 currentObjectLocations.push_back(ptGrid2);
01877 assignmentMap.setVal(ptGrid2, CENTER_REGION);
01878
01879 LINFO(" adding %3d %3d to the center",
01880 ptGrid2.i, ptGrid2.j);
01881 }
01882 else if(side == FAR_SIDE)
01883 {
01884
01885 currentBackgroundLocations.push_back(ptGrid2);
01886 assignmentMap.setVal(ptGrid2, SURROUND_REGION);
01887
01888 LINFO(" adding %3d %3d to the background",
01889 ptGrid2.i, ptGrid2.j);
01890 }
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906 }
01907
01908 if(label2 == UNASSIGNED_REGION)
01909 {
01910
01911 int side = image.getVal(pt2);
01912 LINFO("UN Side: %d", side);
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922 if(side == CLOSER_SIDE || side == FAR_SIDE)
01923 {
01924
01925 uint pos = 0;
01926 for(uint i = 0; i < currentUnassignedLocations.size(); i++)
01927 if(ptGrid2 == currentUnassignedLocations[i])
01928 { pos = i; i = currentUnassignedLocations.size(); }
01929
01930
01931 std::vector<Point2D<int> >::iterator itr =
01932 currentUnassignedLocations.begin();
01933 currentUnassignedLocations.erase(itr+pos);
01934 }
01935 else LINFO("not on the close or far side");
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960 if(side == CLOSER_SIDE)
01961 {
01962
01963 currentObjectLocations.push_back(ptGrid2);
01964 assignmentMap.setVal(ptGrid2, CENTER_REGION);
01965
01966 LINFO(" adding %3d %3d to the center",
01967 ptGrid2.i, ptGrid2.j);
01968 }
01969 else if(side == FAR_SIDE)
01970 {
01971
01972 currentBackgroundLocations.push_back(ptGrid2);
01973 assignmentMap.setVal(ptGrid2, SURROUND_REGION);
01974
01975 LINFO(" adding %3d %3d to the background",
01976 ptGrid2.i, ptGrid2.j);
01977 }
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994 }
01995 }
01996 }
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057 }
02058
02059
02060 void SalientRegionSegmenter::displayDistributionSetup
02061 (Segment segment, Point2D<int> pt,
02062 std::vector<Point2D<int> > pts2,
02063 std::vector<Point2D<int> > pts3)
02064 {
02065
02066 Image<PixRGB<byte> > ima = itsImage;
02067 uint w = ima.getWidth();
02068 uint h = ima.getHeight();
02069
02070 Image<float> fIma(luminance(ima));
02071 Image<float> tempFIma = fIma;
02072 inplaceNormalize(tempFIma, 0.0f,255.0f);
02073 Image<byte> bIma(tempFIma);
02074
02075
02076 float mVal = 32;
02077 float bVal = 255 - mVal;
02078 Image<byte> dImaR, dImaG, dImaB;
02079 getComponents(ima, dImaR, dImaG, dImaB);
02080 inplaceNormalize(dImaR, byte(0), byte(mVal));
02081 inplaceNormalize(dImaG, byte(0), byte(mVal));
02082 inplaceNormalize(dImaB, byte(0), byte(mVal));
02083 Image<PixRGB<byte> > dIma = makeRGB(dImaR,dImaG,dImaB);
02084
02085 Image<PixRGB<byte> > dispIma(4*w,2*h,ZEROS);
02086
02087 inplacePaste (dispIma, ima, Point2D<int>(0,0));
02088
02089 Image<float> stateMapR(w,h, ZEROS);
02090 Image<float> stateMapG(w,h, ZEROS);
02091 Image<float> stateMapB(w,h, ZEROS);
02092
02093
02094 std::vector<Point2D<int> > cores;
02095 std::vector<Point2D<int> > center;
02096 std::vector<Point2D<int> > surround;
02097 std::vector<Point2D<int> > unassigned;
02098
02099 cores.push_back(Point2D<int>(152, 40));
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178 for(uint i = 0; i < cores.size(); i++)
02179 {
02180 Rectangle r = Rectangle::tlbrO
02181 (cores[i].j-4, cores[i].i-4,
02182 cores[i].j+4, cores[i].i+4);
02183 drawFilledRect(stateMapB, r, 0.5F);
02184 }
02185
02186 for(uint i = 0; i < center.size(); i++)
02187 {
02188 Rectangle r = Rectangle::tlbrO
02189 (center[i].j-4, center[i].i-4,
02190 center[i].j+4, center[i].i+4);
02191 drawFilledRect(stateMapR, r, 0.5F);
02192 }
02193
02194 for(uint i = 0; i < surround.size(); i++)
02195 {
02196 Rectangle r = Rectangle::tlbrO
02197 (surround[i].j-4, surround[i].i-4,
02198 surround[i].j+4, surround[i].i+4);
02199 drawFilledRect(stateMapG, r, 0.5F);
02200 }
02201
02202 for(uint i = 0; i < unassigned.size(); i++)
02203 {
02204 Rectangle r = Rectangle::tlbrO
02205 (unassigned[i].j-4, unassigned[i].i-4,
02206 unassigned[i].j+4, unassigned[i].i+4);
02207 drawFilledRect(stateMapR, r, 0.5F);
02208 drawFilledRect(stateMapG, r, 0.5F);
02209 }
02210
02211
02212
02213 int grad = 8;
02214 for(uint i = grad; i < w; i++)
02215 for(uint j = grad; j < h; j++)
02216 {
02217 if(i%grad == 0 && j%grad == 0)
02218 {
02219 drawCross(stateMapR, Point2D<int>(i,j), 0.5F, 1);
02220 drawCross(stateMapG, Point2D<int>(i,j), 0.5F, 1);
02221 drawCross(stateMapB, Point2D<int>(i,j), 0.5F, 1);
02222 }
02223 }
02224
02225
02226
02227 for(uint i = 0; i < pts2.size(); i++)
02228 {
02229
02230 if(stateMapR.coordsOk(pts2[i]))
02231 {
02232 stateMapR.setVal(pts2[i], 0.25F);
02233
02234
02235 }
02236 }
02237
02238
02239
02240 for(uint i = 0; i < pts3.size(); i++)
02241 {
02242
02243 if(stateMapR.coordsOk(pts3[i]))
02244 {
02245
02246 stateMapG.setVal(pts3[i], 0.25F);
02247
02248 }
02249 }
02250
02251
02252 int rad = NEIGHBORHOOD_RADIUS;
02253 for(int i = -rad; i <= rad; i++)
02254 for(int j = -rad; j <= rad; j++)
02255 {
02256 bool isWithinCircle = ((i*i+j*j) <= (rad*rad));
02257
02258 Point2D<int> pt2 = pt + Point2D<int>(i,j);
02259 if(itsImage.coordsOk(pt2) && isWithinCircle)
02260 {
02261 stateMapR.setVal(pt2, 0.5F);
02262
02263
02264 }
02265 }
02266
02267 drawDisk(stateMapR, pt, 2, 1.0F);
02268 drawDisk(stateMapG, pt, 2, 1.0F);
02269 drawDisk(stateMapB, pt, 2, 1.0F);
02270
02271
02272
02273
02274
02275
02276 rutz::shared_ptr<Contour> contour =
02277 itsContourBoundaries[segment.contourIndex];
02278
02279 int hstep = BOUNDARY_STEP_SIZE/2;
02280 uint start = segment.segStartIndex;
02281 uint end = segment.segEndIndex;
02282
02283
02284 for(uint i = 0; i < contour->edgels.size(); i++)
02285 {
02286 rutz::shared_ptr<Edgel> edgel = contour->edgels[i];
02287
02288 uint aind = edgel->angleIndex;
02289 float baind =
02290 fmod((aind+(NUM_RIDGE_DIRECTIONS/2)),NUM_RIDGE_DIRECTIONS);
02291
02292 float dx = cos(baind * M_PI/4.0) * hstep;
02293 float dy = sin(baind * M_PI/4.0) * hstep;
02294
02295 Point2D<int> pt = edgel->pt;
02296 Point2D<int> p1 = pt + Point2D<int>( dx+.5, dy+.5);
02297 Point2D<int> p2 = pt + Point2D<int>(-dx-.5, -dy-.5);
02298
02299 if(i >= start && i <= end)
02300 {
02301 drawLine(stateMapR, p1, p2, 1.0F);
02302 drawLine(stateMapG, p1, p2, 1.0F);
02303 drawLine(stateMapB, p1, p2, 1.0F);
02304 }
02305 else
02306 {
02307 drawLine(stateMapR, p1, p2, 0.5F);
02308 drawLine(stateMapG, p1, p2, 0.5F);
02309 drawLine(stateMapB, p1, p2, 0.5F);
02310 }
02311
02312 }
02313
02314 inplaceNormalize(stateMapR, 0.0f,bVal);
02315 inplaceNormalize(stateMapG, 0.0f,bVal);
02316 inplaceNormalize(stateMapB, 0.0f,bVal);
02317 Image<byte> dSMapR(stateMapR);
02318 Image<byte> dSMapG(stateMapG);
02319 Image<byte> dSMapB(stateMapB);
02320 Image<PixRGB<byte> > dSmap = makeRGB(dSMapR, dSMapG, dSMapB);
02321 inplacePaste
02322 (dispIma, Image<PixRGB<byte> >(dIma+dSmap), Point2D<int>(w,0));
02323
02324
02325
02326
02327
02328 itsWin->drawImage(dispIma, 0,0);
02329 Raster::waitForKey();
02330 }
02331
02332
02333 void SalientRegionSegmenter::displayGrowMap
02334 (Image<int> assignmentMap, Point2D<int> currPoint,
02335 std::vector<Point2D<int> > currentObjectLocations,
02336 std::vector<Point2D<int> > currentObjectCoreLocations,
02337 std::vector<Point2D<int> > currentBackgroundLocations,
02338 std::vector<Point2D<int> > currentUnassignedLocations,
02339 Image<bool> isComparedWith, Segment segment)
02340 {
02341
02342 Image<PixRGB<byte> > ima = itsImage;
02343 uint w = ima.getWidth();
02344 uint h = ima.getHeight();
02345
02346 Image<float> fIma(luminance(ima));
02347 Image<float> tempFIma = fIma;
02348 inplaceNormalize(tempFIma, 0.0f,255.0f);
02349 Image<byte> bIma(tempFIma);
02350
02351
02352 float mVal = 32;
02353 float bVal = 255 - mVal;
02354 Image<byte> dImaR, dImaG, dImaB;
02355 getComponents(ima, dImaR, dImaG, dImaB);
02356 inplaceNormalize(dImaR, byte(0), byte(mVal));
02357 inplaceNormalize(dImaG, byte(0), byte(mVal));
02358 inplaceNormalize(dImaB, byte(0), byte(mVal));
02359 Image<PixRGB<byte> > dIma = makeRGB(dImaR,dImaG,dImaB);
02360
02361 Image<PixRGB<byte> > dispIma(4*w,2*h,ZEROS);
02362
02363 inplacePaste (dispIma, ima, Point2D<int>(0,0));
02364
02365 Image<float> stateMapR(w,h, ZEROS);
02366 Image<float> stateMapG(w,h, ZEROS);
02367 Image<float> stateMapB(w,h, ZEROS);
02368
02369 std::vector<Point2D<int> >::iterator oitr =
02370 currentObjectLocations.begin();
02371 std::vector<Point2D<int> >::iterator citr =
02372 currentObjectCoreLocations.begin();
02373 std::vector<Point2D<int> >::iterator sitr =
02374 currentBackgroundLocations.begin();
02375 std::vector<Point2D<int> >::iterator uitr =
02376 currentUnassignedLocations.begin();
02377
02378 for(uint i = 0; i < currentObjectLocations.size(); i++)
02379 {
02380 Point2D<int> pt((*oitr).i*BOUNDARY_STEP_SIZE,
02381 (*oitr).j*BOUNDARY_STEP_SIZE );
02382 Rectangle r = Rectangle::tlbrO(pt.j-4, pt.i-4, pt.j+4, pt.i+4);
02383 drawFilledRect(stateMapR, r, 0.5F);
02384 oitr++;
02385 }
02386
02387 for(uint i = 0; i < currentObjectCoreLocations.size(); i++)
02388 {
02389 Point2D<int> pt((*citr).i*BOUNDARY_STEP_SIZE,
02390 (*citr).j*BOUNDARY_STEP_SIZE );
02391 Rectangle r = Rectangle::tlbrO(pt.j-4, pt.i-4, pt.j+4, pt.i+4);
02392 drawFilledRect(stateMapB, r, 0.5F);
02393 citr++;
02394 }
02395
02396 for(uint i = 0; i < currentBackgroundLocations.size(); i++)
02397 {
02398 Point2D<int> pt((*sitr).i*BOUNDARY_STEP_SIZE,
02399 (*sitr).j*BOUNDARY_STEP_SIZE );
02400 Rectangle r = Rectangle::tlbrO(pt.j-4, pt.i-4, pt.j+4, pt.i+4);
02401 drawFilledRect(stateMapG, r, 0.5F);
02402 sitr++;
02403 }
02404
02405 for(uint i = 0; i < currentUnassignedLocations.size(); i++)
02406 {
02407 Point2D<int> pt((*uitr).i*BOUNDARY_STEP_SIZE,
02408 (*uitr).j*BOUNDARY_STEP_SIZE );
02409 Rectangle r = Rectangle::tlbrO(pt.j-4, pt.i-4, pt.j+4, pt.i+4);
02410 drawFilledRect(stateMapR, r, 0.5F);
02411 drawFilledRect(stateMapG, r, 0.5F);
02412 uitr++;
02413 }
02414
02415
02416 int grad = 8;
02417 for(uint i = grad; i < w; i++)
02418 for(uint j = grad; j < h; j++)
02419 {
02420 if(i%grad == 0 && j%grad == 0)
02421 {
02422 drawCross(stateMapR, Point2D<int>(i,j), 0.5F, 1);
02423 drawCross(stateMapG, Point2D<int>(i,j), 0.5F, 1);
02424 drawCross(stateMapB, Point2D<int>(i,j), 0.5F, 1);
02425 }
02426 }
02427
02428
02429 rutz::shared_ptr<Contour> contour =
02430 itsContourBoundaries[segment.contourIndex];
02431
02432 int hstep = BOUNDARY_STEP_SIZE/2;
02433 uint start = segment.segStartIndex;
02434 uint end = segment.segEndIndex;
02435
02436
02437 for(uint i = 0; i < contour->edgels.size(); i++)
02438 {
02439 rutz::shared_ptr<Edgel> edgel = contour->edgels[i];
02440
02441 uint aind = edgel->angleIndex;
02442 float baind =
02443 fmod((aind+(NUM_RIDGE_DIRECTIONS/2)),NUM_RIDGE_DIRECTIONS);
02444
02445 float dx = cos(baind * M_PI/4.0) * hstep;
02446 float dy = sin(baind * M_PI/4.0) * hstep;
02447
02448 Point2D<int> pt = edgel->pt;
02449 Point2D<int> p1 = pt + Point2D<int>( dx+.5, dy+.5);
02450 Point2D<int> p2 = pt + Point2D<int>(-dx-.5, -dy-.5);
02451
02452 if(i >= start && i <= end)
02453 {
02454 drawLine(stateMapR, p1, p2, 1.0F);
02455 drawLine(stateMapG, p1, p2, 1.0F);
02456 drawLine(stateMapB, p1, p2, 1.0F);
02457 }
02458 else
02459 {
02460 drawLine(stateMapR, p1, p2, 0.5F);
02461 drawLine(stateMapG, p1, p2, 0.5F);
02462 drawLine(stateMapB, p1, p2, 0.5F);
02463 }
02464
02465 }
02466
02467 inplaceNormalize(stateMapR, 0.0f,bVal);
02468 inplaceNormalize(stateMapG, 0.0f,bVal);
02469 inplaceNormalize(stateMapB, 0.0f,bVal);
02470 Image<byte> dSMapR(stateMapR);
02471 Image<byte> dSMapG(stateMapG);
02472 Image<byte> dSMapB(stateMapB);
02473 Image<PixRGB<byte> > dSmap = makeRGB(dSMapR, dSMapG, dSMapB);
02474 inplacePaste
02475 (dispIma, Image<PixRGB<byte> >(dIma+dSmap), Point2D<int>(w,0));
02476
02477
02478
02479
02480
02481 itsWin->drawImage(dispIma, 0,0);
02482 Raster::waitForKey();
02483 }
02484
02485
02486
02487
02488
02489