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