1 ////////////////////////////////////////////////////////
2 // Name     : edison.cpp
3 // Purpose  : Wrapper class used for segmenation and
4 //            edge detection.
5 // Author   : Chris M. Christoudias
6 // Modified by
7 // Created  : 03/20/2002
8 // Copyright: (c) Chris M. Christoudias
9 // Version  : v0.1
10 ////////////////////////////////////////////////////////
11 
12 #include "defs.h"
13 #include "flags.h"
14 #include "edison.h"
15 #include "../segm/msImageProcessor.h"
16 #include "../edge/BgImage.h"
17 #include "../edge/BgEdge.h"
18 #include "../edge/BgEdgeList.h"
19 #include "../edge/BgEdgeDetect.h"
20 #include "../edge/BgDefaults.h"
21 #include <stdio.h>
22 #include <string.h>
23 
24 ////////////////////////////////////////////////////////
25 //Constructor/Destructor
26 ////////////////////////////////////////////////////////
27 
EDISON(void)28 EDISON::EDISON( void )
29 {
30   height_            = -1;
31   width_             = -1;
32   numEdges_          = -1;
33   numBoundaries_     = -1;
34   inputImage_        = (unsigned char *) NULL;
35   filtImage_         = (unsigned char *) NULL;
36   segmImage_         = (unsigned char *) NULL;
37   gradMap_           = (float *) NULL;
38   confMap_           = (float *) NULL;
39   weightMap_         = (float *) NULL;
40   custMap_           = (float *) NULL;
41   edges_             = (int *)   NULL;
42   boundaries_        = (int *)   NULL;
43   parameterList_     = (void **) NULL;
44   inputDefined_      = false;
45   gradMapDefined_    = false;
46   confMapDefined_    = false;
47   weightMapDefined_  = false;
48   custMapDefined_    = false;
49   filtImageDefined_  = false;
50   segmImageDefined_  = false;
51   edgesDefined_      = false;
52   boundariesDefined_ = false;
53 }
54 
~EDISON(void)55 EDISON::~EDISON( void )
56 {
57   if(inputImage_) delete [] inputImage_;
58   if(filtImage_)  delete [] filtImage_;
59   if(segmImage_)  delete [] segmImage_;
60   if(gradMap_)    delete [] gradMap_;
61   if(confMap_)    delete [] confMap_;
62   if(weightMap_)  delete [] weightMap_;
63   if(custMap_)    delete [] custMap_;
64   if(edges_)      delete [] edges_;
65   if(boundaries_) delete [] boundaries_;
66 }
67 
68 ////////////////////////////////////////////////////////
69 //Input/Output
70 ////////////////////////////////////////////////////////
71 
Save(char * filename,int filetype,int outputtype)72 int EDISON::Save(char *filename, int filetype, int outputtype)
73 {
74   if(!filename) return EXE_NULL_PTR;
75   int error;
76   switch(outputtype)
77     {
78     case OUTPUT_SEGM_BOUNDARIES:
79       if(!boundariesDefined_) return EXE_OUTPUT_UNDEFINED;
80       error = writeImage(filename, (unsigned char *) NULL, boundaries_, numBoundaries_, filetype);
81       break;
82     case OUTPUT_SEGM_IMAGE:
83       if(!segmImageDefined_) return EXE_OUTPUT_UNDEFINED;
84       error = writeImage(filename, segmImage_, (int *) NULL, -1, filetype);
85       break;
86     case OUTPUT_SEGM_IMAGE_BOUNDARIES:
87       if(!(boundariesDefined_ && segmImageDefined_)) return EXE_OUTPUT_UNDEFINED;
88       error = writeImage(filename, segmImage_, boundaries_, numBoundaries_, filetype);
89       break;
90     case OUTPUT_FILT_IMAGE:
91       if(!filtImageDefined_) return EXE_OUTPUT_UNDEFINED;
92       error = writeImage(filename, filtImage_, (int *) NULL, -1, filetype);
93       break;
94     case OUTPUT_FILT_IMAGE_BOUNDARIES:
95       if(!(boundariesDefined_ && filtImageDefined_)) return EXE_OUTPUT_UNDEFINED;
96       error = writeImage(filename, filtImage_, boundaries_, numBoundaries_, filetype);
97       break;
98     case OUTPUT_GRADIENT_MAP:
99       if(!gradMapDefined_) return EXE_OUTPUT_UNDEFINED;
100       error = saveData(filename, gradMap_, filetype);
101       break;
102     case OUTPUT_CONFIDENCE_MAP:
103       if(!confMapDefined_) return EXE_OUTPUT_UNDEFINED;
104       error = saveData(filename, confMap_, filetype);
105       break;
106     case OUTPUT_WEIGHT_MAP:
107       if(!weightMapDefined_) return EXE_OUTPUT_UNDEFINED;
108       error = saveData(filename, weightMap_, filetype);
109       break;
110     case OUTPUT_EDGES:
111       if(!edgesDefined_) return EXE_OUTPUT_UNDEFINED;
112       error = writeImage(filename, (unsigned char *) NULL, edges_, numEdges_, filetype);
113       break;
114     }
115   return error;
116 }
117 
Load(char * filename,int inputtype)118 int EDISON::Load(char *filename, int inputtype)
119 {
120   if(!filename) return EXE_NULL_PTR;
121   int error;
122   switch(inputtype)
123     {
124     case INPUT_IMAGE:
125       error = loadImage(filename);
126       if(!error) Refresh();
127       break;
128     case INPUT_MAP:
129       error = loadMap(filename);
130       break;
131     }
132   return error;
133 }
134 
UseResult(int outputtype)135 int EDISON::UseResult(int outputtype)
136 {
137   switch(outputtype)
138     {
139     case OUTPUT_SEGM_IMAGE:
140       if(!segmImageDefined_) return EXE_OUTPUT_UNDEFINED;
141       memcpy(inputImage_, segmImage_, height_*width_*dim_*sizeof(unsigned char));
142       break;
143     case OUTPUT_FILT_IMAGE:
144       if(!filtImageDefined_) return EXE_OUTPUT_UNDEFINED;
145       memcpy(inputImage_, filtImage_, height_*width_*dim_*sizeof(unsigned char));
146       break;
147     default:
148       break;
149     }
150   Refresh();
151   return NO_ERRORS;
152 }
153 
writeImage(char * filename,unsigned char * image,int * dataPoints,int n,int filetype)154 int EDISON::writeImage(char *filename, unsigned char *image, int *dataPoints, int n, int filetype)
155 {
156   unsigned char *data = new unsigned char [height_ * width_ * dim_];
157   if(!data) return EXE_OUT_OF_MEMORY;
158   memset(data, 0, height_*width_*dim_*sizeof(unsigned char));
159   if(image) memcpy(data, image, height_*width_*dim_*sizeof(unsigned char));
160   if(dataPoints) {
161     int i, j;
162     for(i = 0; i < n; i++) {
163       for(j = 0; j < dim_; j++) {
164 	data[dim_*dataPoints[i]+j] = 255;
165       }
166     }
167   }
168   int error = CmCWriteImage(filename, data, height_, width_, dim_, filetype);
169   delete [] data;
170   return error;
171 }
172 
saveData(char * filename,float * data,int filetype)173 int EDISON::saveData(char *filename, float *data, int filetype)
174 {
175   if(filetype != FILE_MATLAB_ASCII) {
176     unsigned char *imData = new unsigned char[height_*width_];
177     if(!imData) return EXE_OUT_OF_MEMORY;
178     int i;
179     for(i = 0; i < height_*width_; i++) {
180       imData[i] = (int)(255*data[i] + 0.5);
181     }
182     int error = CmCWriteImage(filename, imData, height_, width_, 1, filetype);
183     return error;
184   }
185   int error = CmCWriteMFile(filename, data, height_, width_, dim_);
186   return error;
187 }
188 
loadImage(char * filename)189 int EDISON::loadImage(char *filename)
190 {
191   int error = CmCReadImage(filename, &inputImage_, height_, width_, dim_);
192   if(!error) inputDefined_ = true;
193   return error;
194 }
195 
loadMap(char * filename)196 int EDISON::loadMap(char *filename)
197 {
198   if(!inputDefined_) return EXE_INPUT_UNDEFINED;
199   int error = CmCReadMFile(filename, &custMap_, height_, width_);
200   if(!error) custMapDefined_ = true;
201   return error;
202 }
203 
Refresh(void)204 void EDISON::Refresh( void )
205 {
206   //de-allocate all memory
207   if(filtImage_)  delete [] filtImage_;
208   if(segmImage_)  delete [] segmImage_;
209   if(gradMap_)    delete [] gradMap_;
210   if(confMap_)    delete [] confMap_;
211   if(weightMap_)  delete [] weightMap_;
212   if(custMap_)    delete [] custMap_;
213   if(edges_)      delete [] edges_;
214   if(boundaries_) delete [] boundaries_;
215 
216   //reset flags
217   gradMapDefined_    = false;
218   confMapDefined_    = false;
219   weightMapDefined_  = false;
220   custMapDefined_    = false;
221   filtImageDefined_  = false;
222   segmImageDefined_  = false;
223   edgesDefined_      = false;
224   boundariesDefined_ = false;
225 }
226 
227 ////////////////////////////////////////////////////////
228 //Set Parameters
229 ////////////////////////////////////////////////////////
230 
SetParameters(void ** parameterList)231 void EDISON::SetParameters(void **parameterList)
232 {
233   parameterList_ = parameterList;
234 }
235 
236 ////////////////////////////////////////////////////////
237 //Edge Detection
238 ////////////////////////////////////////////////////////
239 
EdgeDetect(void)240 int EDISON::EdgeDetect( void )
241 {
242 
243   //make sure an input image was defined
244   if(!inputDefined_) return EXE_INPUT_UNDEFINED;
245 
246   //prompt the user
247   CmCPrompt("\n-------------------------------------------------------------------------\n");
248   CmCPrompt("Performing EDGE DETECTION:\n\n");
249   CmCPrompt("\tUsing Parameters:\n\n");
250 
251   //make sure all necessary parameters are available
252   int i;
253   if(!parameterList_[PARAM_GRADIENT_WINDOW_RADIUS]) return EXE_MISSING_PARAM;
254   for(i = 7; i < PARAM_NUM; i++) {
255     if(!parameterList_[i]) return EXE_MISSING_PARAM;
256   }
257 
258   //obtain parameters
259   int gradWindRad     = *((int *)(parameterList_[PARAM_GRADIENT_WINDOW_RADIUS]));
260   int minLength       = *((int *)(parameterList_[PARAM_MINIMUM_LENGTH]));
261   float nmxRank       = *((float *)(parameterList_[PARAM_NMX_RANK]));
262   float nmxConf       = *((float *)(parameterList_[PARAM_NMX_CONF]));
263   int   nmxType       = *((int *)(parameterList_[PARAM_NMX_TYPE]));
264   float hystHighRank  = *((float *)(parameterList_[PARAM_HYSTERISIS_HIGH_RANK]));
265   float hystHighConf  = *((float *)(parameterList_[PARAM_HYSTERISIS_HIGH_CONF]));
266   int   hystHighType  = *((int *)(parameterList_[PARAM_HYSTERISIS_HIGH_TYPE]));
267   float hystLowRank   = *((float *)(parameterList_[PARAM_HYSTERISIS_LOW_RANK]));
268   float hystLowConf   = *((float *)(parameterList_[PARAM_HYSTERISIS_LOW_CONF]));
269   int   hystLowType   = *((int *)(parameterList_[PARAM_HYSTERISIS_LOW_TYPE]));
270 
271   //prompt the user
272   CmCPrompt("\t\tGradient Window Radius\t= %6d\n\t\tMinimum Length\t\t= %6d\n\n", gradWindRad, minLength);
273   CmCPrompt("\t\tNmx. Rank\t\t= %6.4f\n\t\tNmx. Conf\t\t= %6.4f\n\t\tNmx. Curve Type\t\t= %s\n\n",
274 	    nmxRank, nmxConf, CURVETYPE_LIST[nmxType]);
275   CmCPrompt("\t\tHyst. High Rank\t\t= %6.4f\n\t\tHyst. High Conf\t\t= %6.4f\n\t\tHyst. High Curve Type\t= %s",
276 	    hystHighRank, hystHighConf, CURVETYPE_LIST[hystHighType]);
277   CmCPrompt("\n\n");
278   CmCPrompt("\t\tHyst. Low Rank\t\t= %6.4f\n\t\tHyst. Low Conf\t\t= %6.4f\n\t\tHyst. Low Curve Type\t= %s",
279 	    hystLowRank, hystLowConf, CURVETYPE_LIST[hystLowType]);
280   CmCPrompt("\n\n");
281 
282   //convert the input image to grayscale if necessary...
283   BgImage inputImage;
284   if(dim_ == 3) {
285     unsigned char *data = CmCConvertToGrayscale(inputImage_, height_, width_);
286     inputImage.SetImage(data, width_, height_, false);
287     delete [] data;
288   } else
289     inputImage.SetImage(inputImage_, width_, height_, false);
290 
291   //if there are any custom curves attempt to read in there point lists
292   int   n;
293   float *pts;
294   double *ptsX, *ptsY;
295   BgEdgeDetect edgeDetector(gradWindRad);
296   if(hystHighType == CURVE_CUSTOM) {
297     pts = (float *)(parameterList_[PARAM_NUM + 2*CUST_CURVE_HYST_HIGH]);
298     if(!pts) return EXE_POINT_LIST_HIGH;
299     n = *((int *)(parameterList_[PARAM_NUM + 2*CUST_CURVE_HYST_HIGH + 1]));
300     ptsX = new double [n];
301     ptsY = new double [n];
302     for(i = 0; i < n; i++) {
303       ptsX[i] = (double) pts[2*i];
304       ptsY[i] = (double) pts[2*i+1];
305     }
306     edgeDetector.SetCustomHigh(ptsX, ptsY, n);
307     delete [] ptsX;
308     delete [] ptsY;
309   }
310   if(hystLowType == CURVE_CUSTOM) {
311     pts = (float *)(parameterList_[PARAM_NUM + 2*CUST_CURVE_HYST_LOW]);
312     if(!pts) return EXE_POINT_LIST_LOW;
313     n = *((int *)(parameterList_[PARAM_NUM + 2*CUST_CURVE_HYST_LOW + 1]));
314     ptsX = new double [n];
315     ptsY = new double [n];
316     for(i = 0; i < n; i++) {
317       ptsX[i] = (double) pts[2*i];
318       ptsY[i] = (double) pts[2*i+1];
319     }
320     edgeDetector.SetCustomLow(ptsX, ptsY, n);
321     delete [] ptsX;
322     delete [] ptsY;
323   }
324 
325   //edge detect the input image
326   BgEdgeList   edgeList;
327   edgeDetector.DoEdgeDetect(&inputImage, &edgeList, nmxRank, nmxConf, hystHighRank, hystHighConf,
328 			    hystLowRank, hystLowConf, minLength, nmxType, hystHighType, hystLowType);
329   if(edgesDefined_) delete [] edges_;
330   edges_ = new int [height_ * width_];
331   int *edgex, *edgey;
332   edgex = new int [height_ * width_];
333   edgey = new int [height_ * width_];
334   edgeList.GetAllEdgePoints(edgex, edgey, &numEdges_);
335   for(i = 0; i < numEdges_; i++) {
336     edges_[i] = edgey[i]*width_ + edgex[i];
337   }
338   edgesDefined_ = true;
339   delete [] edgex;
340   delete [] edgey;
341 
342   //obtain rank and confidence maps
343   if(gradMapDefined_) delete [] gradMap_;
344   if(confMapDefined_) delete [] confMap_;
345   gradMap_ = new float [height_ * width_];
346   confMap_ = new float [height_ * width_];
347   if(!gradMap_ || !confMap_) return EXE_OUT_OF_MEMORY;
348   memcpy(gradMap_, edgeDetector.permRank_, height_ * width_ * sizeof(float));
349   memcpy(confMap_, edgeDetector.permConf_, height_ * width_ * sizeof(float));
350   gradMapDefined_ = true;
351   confMapDefined_ = true;
352 
353   //prompt the user
354   CmCPrompt("-------------------------------------------------------------------------\n");
355 
356   //done.
357   return NO_ERRORS;
358 
359 }
360 
361 ////////////////////////////////////////////////////////
362 //Image Segmenation
363 ////////////////////////////////////////////////////////
364 
Filter(void)365 int EDISON::Filter( void )
366 {
367   return meanShift(EDISON_FILTER);
368 }
369 
Fuse(void)370 int EDISON::Fuse( void )
371 {
372   return meanShift(EDISON_FUSE);
373 }
374 
Segment(void)375 int EDISON::Segment( void )
376 {
377   return meanShift(EDISON_SEGMENT);
378 }
379 
meanShift(int action)380 int EDISON::meanShift(int action)
381 {
382 
383   //make sure input has been defined
384   if(!inputDefined_) return EXE_INPUT_UNDEFINED;
385 
386   //obtain parameters...
387   int   sigmaS, minRegion;
388   float sigmaR;
389   char action_str[80];
390   action_str[0] = 0; //initialize string
391   if(CmCSynergistic) strcpy(action_str, "SYNERGISTIC ");
392   if(!parameterList_[PARAM_SPEEDUP]) return EXE_MISSING_PARAM;
393   switch(action) {
394   case EDISON_FILTER:
395     strcat(action_str, "IMAGE FILTERING");
396     if(parameterList_[PARAM_SPATIAL_BANDWIDTH]) {
397       sigmaS = *((int *)(parameterList_[PARAM_SPATIAL_BANDWIDTH]));
398       if(parameterList_[PARAM_RANGE_BANDWIDTH]) {
399 	sigmaR = *((float *)(parameterList_[PARAM_RANGE_BANDWIDTH]));
400 	break;
401       }
402     }
403     return EXE_MISSING_PARAM;
404   case EDISON_FUSE:
405     strcat(action_str, "IMAGE REGION FUSION");
406     if(parameterList_[PARAM_RANGE_BANDWIDTH]) {
407       sigmaR = *((float *)(parameterList_[PARAM_RANGE_BANDWIDTH]));
408       if(parameterList_[PARAM_MINIMUM_REGION_AREA]) {
409 	minRegion = *((int *)(parameterList_[PARAM_MINIMUM_REGION_AREA]));
410 	break;
411       }
412     }
413     return EXE_MISSING_PARAM;
414   case EDISON_SEGMENT:
415     strcat(action_str, "IMAGE SEGMENTATION");
416     if(parameterList_[PARAM_SPATIAL_BANDWIDTH]) {
417       sigmaS = *((int *)(parameterList_[PARAM_SPATIAL_BANDWIDTH]));
418       if(parameterList_[PARAM_RANGE_BANDWIDTH]) {
419 	sigmaR = *((float *)(parameterList_[PARAM_RANGE_BANDWIDTH]));
420 	if(parameterList_[PARAM_MINIMUM_REGION_AREA]) {
421 	  minRegion = *((int *)(parameterList_[PARAM_MINIMUM_REGION_AREA]));
422 	  break;
423 	}
424       }
425     }
426     return EXE_MISSING_PARAM;
427   }
428 
429   //check for synergistic parameters
430   if(CmCSynergistic) {
431     int i;
432     for(i = PARAM_GRADIENT_WINDOW_RADIUS; i <= PARAM_EDGE_STRENGTH_THRESHOLD; i++) {
433       if(!parameterList_[i]) return EXE_MISSING_PARAM;
434     }
435   }
436 
437   //prompt the user
438   CmCPrompt("\n-------------------------------------------------------------------------\n");
439   CmCPrompt("Performing %s:\n\n", action_str);
440   CmCPrompt("\tUsing Parameters:\n\n");
441   CmCPrompt("\t\tSpatial Bandwidth\t= %6d\n\t\tRange Bandwidth\t\t= %6.4f\n\t\tMinimum Region Area\t= %6d",
442 	    sigmaS, sigmaR, minRegion);
443   if(CmCSynergistic) {
444     int   gradWindRad = *((int *)(parameterList_[PARAM_GRADIENT_WINDOW_RADIUS]));
445     float threshold   = *((float *)(parameterList_[PARAM_EDGE_STRENGTH_THRESHOLD]));
446     float mixture     = *((float *)(parameterList_[PARAM_MIXTURE_PARAMETER]));
447     CmCPrompt("\n\n\t\tGradient Window Radius\t= %6d\n\t\tEdge Strength Threshold\t= %6.4f\n\t\t",
448 	      gradWindRad, threshold);
449     CmCPrompt("Mixture Parameter\t= %6.4f\n\n", mixture);
450   }
451 
452   //create image processing object
453   msImageProcessor iProc;
454 
455   //define the image to be processed as the input image
456   if(dim_ == 3)
457     iProc.DefineImage(inputImage_, COLOR, height_, width_);
458   else
459     iProc.DefineImage(inputImage_, GRAYSCALE, height_, width_);
460   if(iProc.ErrorStatus) {
461     return EXE_ERROR;
462   }
463 
464   //compute and set weight map if synergistic segmentation is requested
465   if(CmCSynergistic) {
466     if(CmCUseCustomWeightMap) {
467       if(!custMapDefined_) return EXE_INPUT_UNDEFINED;
468       iProc.SetWeightMap(custMap_, *((float *)(parameterList_[PARAM_EDGE_STRENGTH_THRESHOLD])));
469     } else {
470       int error = ComputeWeightMap();
471       if(error) return error;
472       iProc.SetWeightMap(weightMap_, *((float *)(parameterList_[PARAM_EDGE_STRENGTH_THRESHOLD])));
473     }
474     if(iProc.ErrorStatus) {
475       return EXE_ERROR;
476     }
477   }
478 
479   switch(action) {
480   case EDISON_FILTER:
481     //filter the input image
482     iProc.Filter(sigmaS, sigmaR, (SpeedUpLevel)(*(int *)(parameterList_[PARAM_SPEEDUP])));
483     if(iProc.ErrorStatus) {
484       return EXE_ERROR;
485     }
486 
487     //obtain the output
488     if(filtImageDefined_) delete [] filtImage_;
489     filtImage_ = new unsigned char [height_ * width_ * dim_];
490     iProc.GetResults(filtImage_);
491     if(iProc.ErrorStatus) {
492       return EXE_ERROR;
493     }
494     filtImageDefined_ = true;
495     break;
496   case EDISON_FUSE:
497     //re-define input image if filtered image is defined
498     if(filtImageDefined_) {
499       if(dim_ == 3)
500 	iProc.DefineImage(filtImage_, COLOR, height_, width_);
501       else
502 	iProc.DefineImage(filtImage_, GRAYSCALE, height_, width_);
503     }
504 
505     //fuse the regions of input image
506     iProc.FuseRegions(sigmaR, minRegion);
507     if(iProc.ErrorStatus) {
508       return EXE_ERROR;
509     }
510 
511     //obtain the output
512     if(segmImageDefined_) delete [] segmImage_;
513     segmImage_ = new unsigned char [height_ * width_ * dim_];
514     iProc.GetResults(segmImage_);
515     if(iProc.ErrorStatus) {
516       return EXE_ERROR;
517     }
518     segmImageDefined_ = true;
519     break;
520   case EDISON_SEGMENT:
521     //filter the image
522     iProc.Filter(sigmaS, sigmaR, (SpeedUpLevel)(*(int *)(parameterList_[PARAM_SPEEDUP])));
523     if(iProc.ErrorStatus) {
524       return EXE_ERROR;
525     }
526 
527     //obtain the filtered image
528     if(filtImageDefined_) delete [] filtImage_;
529     filtImage_ = new unsigned char [height_ * width_ * dim_];
530     iProc.GetResults(filtImage_);
531     if(iProc.ErrorStatus) {
532       return EXE_ERROR;
533     }
534     filtImageDefined_ = true;
535 
536     //fuse regions
537     iProc.FuseRegions(sigmaR, minRegion);
538     if(iProc.ErrorStatus) {
539       return EXE_ERROR;
540     }
541 
542     //obtain the segmented image
543     if(segmImageDefined_) delete [] segmImage_;
544     segmImage_ = new unsigned char [height_ * width_ * dim_];
545     iProc.GetResults(segmImage_);
546     if(iProc.ErrorStatus) {
547       return EXE_ERROR;
548     }
549     segmImageDefined_ = true;
550     break;
551   }
552 
553   //define the boundaries
554   RegionList *regionList        = iProc.GetBoundaries();
555   int        *regionIndeces     = regionList->GetRegionIndeces(0);
556   int        numRegions         = regionList->GetNumRegions();
557   numBoundaries_ = 0;
558   int i;
559   for(i = 0; i < numRegions; i++) {
560     numBoundaries_ += regionList->GetRegionCount(i);
561   }
562   if(boundariesDefined_) delete [] boundaries_;
563   boundaries_ = new int [numBoundaries_];
564   for(i = 0; i < numBoundaries_; i++) {
565     boundaries_[i] = regionIndeces[i];
566   }
567   boundariesDefined_ = true;
568 
569   //prompt the user
570   CmCPrompt("-------------------------------------------------------------------------\n\n");
571 
572   //done.
573   return NO_ERRORS;
574 
575 }
576 
ComputeWeightMap(void)577 int EDISON::ComputeWeightMap( void )
578 {
579 
580   //do not do un-necessary computation
581   if(weightMapDefined_ && !CmCGradWinChanged && !CmCMixtureChanged) return NO_ERRORS;
582 
583   //attain necessary parameters...
584   int   gradWindowRadius = *((int *)(parameterList_[PARAM_GRADIENT_WINDOW_RADIUS]));
585   float mixtureParam     = *((float *)(parameterList_[PARAM_MIXTURE_PARAMETER]));
586 
587   //compute gradient and confidence maps
588   if(!gradMapDefined_ || !confMapDefined_ || CmCGradWinChanged) {
589     if(gradMapDefined_) delete [] gradMap_;
590     if(confMapDefined_) delete [] confMap_;
591     gradMap_ = new float [height_ * width_];
592     confMap_ = new float [height_ * width_];
593     if(!gradMap_ || !confMap_) return EXE_OUT_OF_MEMORY;
594     BgEdgeDetect edgeDetector(gradWindowRadius);
595     BgImage inputImage;
596     if(dim_ == 3)
597       inputImage.SetImage(inputImage_, width_, height_, true);
598     else
599       inputImage.SetImage(inputImage_, width_, height_, false);
600     edgeDetector.ComputeEdgeInfo(&inputImage, confMap_, gradMap_);
601   }
602 
603   //compute weight map
604   if(!weightMapDefined_ || !gradMapDefined_ || !confMapDefined_ || CmCGradWinChanged || CmCMixtureChanged) {
605     CmCPrompt("Computing weight map...");
606     if(weightMapDefined_) delete [] weightMap_;
607     weightMap_ = new float [height_ * width_];
608     if(!weightMap_) return EXE_OUT_OF_MEMORY;
609     int i;
610     for(i = 0; i < width_*height_; i++) {
611       if(gradMap_[i] > 0.02) {
612 	weightMap_[i] = mixtureParam*gradMap_[i] + (1 - mixtureParam)*confMap_[i];
613       } else {
614 	weightMap_[i] = 0;
615       }
616     }
617     CmCPrompt("done.\n");
618   }
619 
620   //indicate that maps are now defined
621   gradMapDefined_   = true;
622   confMapDefined_   = true;
623   weightMapDefined_ = true;
624 
625   //indicate that the changed parameters have been accounted for
626   CmCGradWinChanged = false;
627   CmCMixtureChanged = false;
628 
629   //done.
630   return NO_ERRORS;
631 }
632 
633 
634 
635 
636 
637 
638