250 kkint32 absoluteMaximumEdgePixels = totalPixels * 3;
252 kkint32 maxNumOfBorderPoints = 3 * (height + width);
262 #if defined(FFTW_AVAILABLE) 263 fftwf_complex* src = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * maxNumOfBorderPoints);
269 GetFirstPixel (startRow, startCol);
270 if ((startRow < 0) || (startCol < 0) || (PixelCountIn9PixelNeighborhood (startRow, startCol) < 2))
272 cout <<
"Very Bad Starting Point" <<
std::endl;
277 GetNextPixel (scndRow, scndCol);
288 if (numOfBorderPixels > absoluteMaximumEdgePixels)
293 <<
"ContourFollower::FollowContour ***ERROR***" <<
endl 295 <<
" We exceeded the absolute maximum number of possible edge pixels." <<
endl 298 <<
" numOfBorderPixels [" << numOfBorderPixels <<
"]" <<
endl 301 ofstream r (
"c:\\temp\\ContourFollowerFollowContour.log", std::ios_base::ate);
302 r <<
"FileName [" << raster.
FileName () <<
"] ";
303 r <<
"totalPixels [" << totalPixels <<
"] ";
304 r <<
"numOfBorderPixels [" << numOfBorderPixels <<
"]";
313 GetNextPixel (nextRow, nextCol);
315 if ((nextRow == scndRow) && (nextCol == scndCol) &&
316 (lastRow == startRow) && (lastCol == startCol))
321 if (numOfBorderPixels >= maxNumOfBorderPoints)
323 kkint32 newMaxNumOfAngles = maxNumOfBorderPoints * 2;
325 #if defined(FFTW_AVAILABLE) 326 fftwf_complex* newSrc = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * newMaxNumOfAngles);
333 log.
Level (-1) << endl << endl
334 <<
"FollowContour ***ERROR***" << endl
336 <<
"Could not allocate memory needed for contour points." << endl
343 for (x = 0; x < maxNumOfBorderPoints; x++)
345 #if defined(FFTW_AVAILABLE) 346 newSrc[x][0] = src[x][0];
347 newSrc[x][1] = src[x][1];
349 newSrc[x].real (src[x].real ());
350 newSrc[x].imag (src[x].imag ());
355 #if defined(FFTW_AVAILABLE) 365 maxNumOfBorderPoints = newMaxNumOfAngles;
368 #if defined(FFTW_AVAILABLE) 369 src[numOfBorderPixels][0] = (float)nextRow;
370 src[numOfBorderPixels][1] = (float)nextCol;
372 src[numOfBorderPixels].real ((
float)nextRow);
373 src[numOfBorderPixels].imag ((
float)nextCol);
382 float centerRow = (float)totalRow / (
float)numOfBorderPixels;
383 float centerCol = (float)totalCol / (
float)numOfBorderPixels;
388 for (x = 0; x < numOfBorderPixels; x++)
390 #if defined(FFTW_AVAILABLE) 391 src[x][0] = (src[x][0] - centerRow);
392 src[x][1] = (src[x][1] - centerCol);
393 totalRe += src[x][0];
394 totalIm += src[x][1];
396 src[x].real ((src[x].real () - centerRow));
397 src[x].imag ((src[x].imag () - centerCol));
398 totalRe += src[x].real ();
399 totalIm += src[x].imag ();
403 #if defined(FFTW_AVAILABLE) 404 fftwf_complex* dest = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * maxNumOfBorderPoints);
405 fftwf_plan plan = fftwCreateOneDPlan (numOfBorderPixels, src, dest, FFTW_FORWARD, FFTW_ESTIMATE);
406 fftwf_execute (plan);
407 fftwDestroyPlan (plan);
412 plan.Transform (src, dest);
415 kkint32 numOfedgePixels = numOfBorderPixels;
419 for (x = 0; x < numOfBuckets; x++)
421 countourFreq[x] = 0.0f;
426 float middle = numOfBorderPixels / (float)2.0;
427 float r1 = middle / (float)2.0;
428 float r2 = middle * ( (float)3.0 / (
float)4.0);
429 float r3 = middle * ( (float)7.0 / (
float)8.0);
430 float r4 = middle * ((float)15.0 / (
float)16.0);
435 if (numOfBorderPixels < 8)
443 fourierDescriptors[ 0] =
CalcMagnitude (dest, numOfBorderPixels - 1) / normalizationFactor;
445 fourierDescriptors[ 1] =
CalcMagnitude (dest, 2) / normalizationFactor;
446 fourierDescriptors[ 2] =
CalcMagnitude (dest, numOfBorderPixels - 2) / normalizationFactor;
448 fourierDescriptors[ 3] =
CalcMagnitude (dest, 3) / normalizationFactor;
449 fourierDescriptors[ 4] =
CalcMagnitude (dest, numOfBorderPixels - 3) / normalizationFactor;
451 fourierDescriptors[ 5] =
CalcMagnitude (dest, 4) / normalizationFactor;
452 fourierDescriptors[ 6] =
CalcMagnitude (dest, numOfBorderPixels - 4) / normalizationFactor;
454 fourierDescriptors[ 7] =
CalcMagnitude (dest, 5) / normalizationFactor;
455 fourierDescriptors[ 8] =
CalcMagnitude (dest, numOfBorderPixels - 5) / normalizationFactor;
457 fourierDescriptors[ 9] =
CalcMagnitude (dest, 6) / normalizationFactor;
458 fourierDescriptors[10] =
CalcMagnitude (dest, numOfBorderPixels - 6) / normalizationFactor;
460 fourierDescriptors[11] =
CalcMagnitude (dest, 7) / normalizationFactor;
461 fourierDescriptors[12] =
CalcMagnitude (dest, numOfBorderPixels - 7) / normalizationFactor;
463 fourierDescriptors[13] =
CalcMagnitude (dest, 8) / normalizationFactor;
464 fourierDescriptors[14] =
CalcMagnitude (dest, numOfBorderPixels - 8) / normalizationFactor;
467 for (x = 1; x < (numOfBorderPixels - 1); x++)
474 deltaX = (float)fabs ((
float)x - middle);
478 countourFreq[0] = countourFreq[0] + mag;
482 else if (deltaX < r2)
484 countourFreq[1] = countourFreq[1] + mag;
488 else if (deltaX < r3)
490 countourFreq[2] = countourFreq[2] + mag;
494 else if (deltaX < r4)
496 countourFreq[3] = countourFreq[3] + mag;
502 countourFreq[4] = countourFreq[4] + mag;
507 for (x = 0; x < numOfBuckets; ++x)
511 countourFreq[x] = 0.0;
515 countourFreq[x] = countourFreq[x] / (float)count[x];
519 #if defined(FFTW_AVAILABLE) 520 fftwf_free (src); src = NULL;
521 fftwf_free (dest); dest = NULL;
523 delete src; src = NULL;
524 delete dest; dest = NULL;
526 delete[] count; count = NULL;
528 return numOfedgePixels;
HTMLReport &__cdecl endl(HTMLReport &htmlReport)
std::complex< DftType > DftComplexType
RunLog & Level(kkint32 _level)
float CalcMagnitude(KK_DFT1D_Float::DftComplexType *dest, kkint32 index)
const KKStr & FileName() const