17 #if defined(FFTW_AVAILABLE) 69 if ((row < 0) || (row >= height))
return 0;
70 if ((col < 0) || (col >= width))
return 0;
71 return rows[row][col];
80 if (PixelValue (row - 1, col - 1) > backgroundPixelTH) ++count;
81 if (PixelValue (row - 1, col ) > backgroundPixelTH) ++count;
82 if (PixelValue (row - 1, col + 1) > backgroundPixelTH) ++count;
83 if (PixelValue (row , col - 1) > backgroundPixelTH) ++count;
84 if (PixelValue (row , col ) > backgroundPixelTH) ++count;
85 if (PixelValue (row , col + 1) > backgroundPixelTH) ++count;
86 if (PixelValue (row + 1, col - 1) > backgroundPixelTH) ++count;
87 if (PixelValue (row + 1, col ) > backgroundPixelTH) ++count;
88 if (PixelValue (row + 1, col + 1) > backgroundPixelTH) ++count;
101 startRow = height / 2;
104 while (startCol < width)
106 if ((rows[startRow][startCol] > backgroundPixelTH) && (PixelCountIn9PixelNeighborhood (startRow, startCol) > 1))
111 if (startCol >= width)
121 for (row = 0; ((row < height) && (!found)); ++row)
123 for (col = 0; ((col < width) && (!found)); ++col)
125 if ((rows[row][col] > backgroundPixelTH) && (PixelCountIn9PixelNeighborhood (row, col) > 1))
136 startRow = startCol = -1;
151 fromDir = lastDir + 4;
154 fromDir = fromDir - 8;
156 bool nextPixelFound =
false;
160 while (!nextPixelFound)
163 nextDir = nextDir - 8;
169 (nextRow >= height) ||
176 else if (rows[nextRow][nextCol] > backgroundPixelTH)
178 nextPixelFound =
true;
194 #if defined(FFTW_AVAILABLE) 195 float CalcMagnitude (fftwf_complex* dest,
200 mag = (
float)sqrt (dest[index][0] * dest[index][0] + dest[index][1] * dest[index][1]);
208 double rp = (
float)dest[index].real ();
209 double ip = (
float)dest[index].imag ();
210 return (
float)sqrt (rp * rp + ip * ip);
221 float fourierDescriptors[15],
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);
265 KK_DFT1D_Float::DftComplexType* src =
new KK_DFT1D_Float::DftComplexType[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)
292 log.Level (-1) << endl << endl << endl
293 <<
"ContourFollower::FollowContour ***ERROR***" << endl
295 <<
" We exceeded the absolute maximum number of possible edge pixels." << endl
297 <<
" FileName [" << raster.FileName () <<
"]" << 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);
328 KK_DFT1D_Float::DftComplexType* newSrc =
new KK_DFT1D_Float::DftComplexType[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);
411 KK_DFT1D_Float::DftComplexType* dest =
new KK_DFT1D_Float::DftComplexType[numOfBorderPixels];
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)
441 float normalizationFactor = CalcMagnitude (dest, 1);
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++)
472 mag = CalcMagnitude (dest, 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;
555 kkint32 maxNumOfBorderPoints = 3 * (height + width);
566 #if defined(FFTW_AVAILABLE) 567 fftwf_complex* src = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * maxNumOfBorderPoints);
569 KK_DFT1D_Float::DftComplexType* src =
new KK_DFT1D_Float::DftComplexType[maxNumOfBorderPoints];
572 GetFirstPixel (startRow, startCol);
573 if ((startRow < 0) || (startCol < 0) || (PixelCountIn9PixelNeighborhood (startRow, startCol) < 2))
575 cout <<
"Very Bad Starting Point" << std::endl;
580 GetNextPixel (scndRow, scndCol);
593 GetNextPixel (nextRow, nextCol);
595 if ((nextRow == scndRow) && (nextCol == scndCol) &&
596 (lastRow == startRow) && (lastCol == startCol))
601 if (numOfBorderPixels >= maxNumOfBorderPoints)
603 kkint32 newMaxNumOfAngles = maxNumOfBorderPoints * 2;
605 #if defined(FFTW_AVAILABLE) 606 fftwf_complex* newSrc = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * newMaxNumOfAngles);
608 KK_DFT1D_Float::DftComplexType* newSrc =
new KK_DFT1D_Float::DftComplexType[newMaxNumOfAngles];
612 for (x = 0; x < maxNumOfBorderPoints; x++)
614 #if defined(FFTW_AVAILABLE) 615 newSrc[x][0] = src[x][0];
616 newSrc[x][1] = src[x][1];
618 newSrc[x].real (src[x].real ());
619 newSrc[x].imag (src[x].imag ());
623 #if defined(FFTW_AVAILABLE) 633 maxNumOfBorderPoints = newMaxNumOfAngles;
636 #if defined(FFTW_AVAILABLE) 637 src[numOfBorderPixels][0] = (
float)nextRow;
638 src[numOfBorderPixels][1] = (
float)nextCol;
640 src[numOfBorderPixels].real ((
float)nextRow);
641 src[numOfBorderPixels].imag ((
float)nextCol);
650 float centerRow = (
float)totalRow / (
float)numOfBorderPixels;
651 float centerCol = (
float)totalCol / (
float)numOfBorderPixels;
656 for (x = 0; x < numOfBorderPixels; x++)
658 #if defined(FFTW_AVAILABLE) 659 src[x][0] = src[x][0] - centerRow;
660 src[x][1] = src[x][1] - centerCol;
661 totalRe+= (
float)src[x][0];
662 totalIm+= (
float)src[x][1];
664 src[x].real (src[x].real () - centerRow);
665 src[x].imag (src[x].imag () - centerCol);
666 totalRe+= (
float)src[x].real ();
667 totalIm+= (
float)src[x].imag ();
671 kkint32 numOfedgePixels = numOfBorderPixels;
673 #if defined(FFTW_AVAILABLE) 674 fftwf_complex* dest = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * maxNumOfBorderPoints);
675 fftwf_plan plan = fftwCreateOneDPlan (numOfBorderPixels, src, dest, FFTW_FORWARD, FFTW_ESTIMATE);
676 fftwf_execute (plan);
677 fftwDestroyPlan (plan);
681 KK_DFT1D_Float::DftComplexType* dest =
new KK_DFT1D_Float::DftComplexType[numOfBorderPixels];
682 plan.Transform (src, dest);
687 for (x = 0; x < numOfBuckets; x++)
689 countourFreq[x] = 0.0;
693 float middle = (
float)numOfBorderPixels / (
float)2.0;
695 float r0 = middle * ( (
float) 8.0 / (
float)16.0);
696 float r1 = middle * ( (
float)10.0 / (
float)16.0);
697 float r2 = middle * ( (
float)12.0 / (
float)16.0);
698 float r3 = middle * ( (
float)13.0 / (
float)16.0);
706 for (x = 1; x < numOfBorderPixels; x++)
712 #if defined(FFTW_AVAILABLE) 713 mag = (
float)sqrt (dest[x][0] * dest[x][0] + dest[x][1] * dest[x][1]);
715 mag = (
float)sqrt (dest[x].real () * dest[x].real () + dest[x].imag () * dest[x].imag ());
718 deltaX = (
float)x - middle;
720 if (fabs (deltaX) < r0)
726 deltaX = fabs (deltaX);
728 if (x == 1) region = 0;
729 else if (x == 2) region = 1;
730 else if (x == 3) region = 2;
731 else if (x == 4) region = 3;
732 else if (deltaX >= r3) region = 4;
733 else if (deltaX >= r2) region = 5;
734 else if (deltaX >= r1) region = 6;
740 if (x == (numOfBorderPixels - 1)) region = 15;
741 else if (x == (numOfBorderPixels - 2)) region = 14;
742 else if (x == (numOfBorderPixels - 3)) region = 13;
743 else if (x == (numOfBorderPixels - 4)) region = 12;
744 else if (deltaX >= r3) region = 11;
745 else if (deltaX >= r2) region = 10;
746 else if (deltaX >= r1) region = 9;
750 countourFreq[region] = countourFreq[region] + mag;
754 for (x = 0; x < numOfBuckets; x++)
758 countourFreq[x] = 0.0;
762 countourFreq[x] = countourFreq[x] / (
float)count[x];
766 #if defined(FFTW_AVAILABLE) 767 fftwf_free (src); src = NULL;
768 fftwf_free (dest); dest = NULL;
770 delete[] src; src = NULL;
771 delete[] dest; dest = NULL;
778 return numOfedgePixels;
801 GetFirstPixel (startRow, startCol);
802 if ((startRow < 0) || (startCol < 0) || (PixelCountIn9PixelNeighborhood (startRow, startCol) < 2))
806 cout <<
"Very Bad Starting Point" << std::endl;
810 GetNextPixel (scndRow, scndCol);
823 GetNextPixel (nextRow, nextCol);
825 if ((nextRow == scndRow) && (nextCol == scndCol) &&
826 (lastRow == startRow) && (lastCol == startCol))
831 points->PushOnBack (
new Point (nextRow, nextCol));
850 if (size == curMaskSize)
860 for (x = 0; x < curMaskSize; x++)
862 delete fourierMask[x];
863 fourierMask[x] = NULL;
866 delete[] fourierMask;
871 for (x = 0; x < size; x++)
886 for (
kkint32 m = 0; m < size; m++)
888 complex<
double> mc (m, 0);
890 for (
kkint32 k = 0; k < size; k++)
892 complex<
double> kc (k, 0);
897 fourierMask[m][k] = exp (MinusOne * j * Two * Pi * kc * mc / M);
899 double exponetPart = 2.0 * 3.14159265359 * (
double)k * (
double)m / (
double)size;
900 double realPart = cos (exponetPart);
901 double imgPart = -sin (exponetPart);
903 if (realPart != fourierMask[m][k].real ())
908 if (imgPart != fourierMask[m][k].imag ())
930 if (size == curRevMaskSize)
931 return revFourierMask;
941 for (x = 0; x < curRevMaskSize; x++)
943 delete revFourierMask[x];
944 revFourierMask[x] = NULL;
947 delete[] revFourierMask;
948 revFourierMask = NULL;
953 for (x = 0; x < size; x++)
957 curRevMaskSize = size;
968 for (
kkint32 m = 0; m < size; m++)
970 complex<
double> mc (m, 0);
972 for (
kkint32 k = 0; k < size; k++)
974 complex<
double> kc (k, 0);
979 revFourierMask[m][k] = exp (PositiveOne * j * Two * Pi * kc * mc / M);
982 double exponetPart = 2.0 * 3.14159265359 * (
double)k * (
double)m / (
double)size;
983 double realPart = cos (exponetPart);
984 double imgPart = sin (exponetPart);
986 if (realPart != revFourierMask[m][k].real ())
991 if (imgPart != revFourierMask[m][k].imag ())
998 return revFourierMask;
1005 float* countourFreq,
1023 kkint32 numOfBorderPixels = 0;
1031 GetFirstPixel (startRow, startCol);
1032 if ((startRow < 0) || (startCol < 0) || (PixelCountIn9PixelNeighborhood (startRow, startCol) < 2))
1034 cout <<
"Vary Bad Starting Point" << std::endl;
1039 GetNextPixel (scndRow, scndCol);
1053 GetNextPixel (nextRow, nextCol);
1055 if ((nextRow == scndRow) && (nextCol == scndCol) &&
1056 (lastRow == startRow) && (lastCol == startCol))
1061 points->PushOnBack (
new Point (nextRow, nextCol));
1063 numOfBorderPixels++;
1067 #if defined(FFTW_AVAILABLE) 1068 fftwf_complex* src = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * numOfBuckets);
1070 KK_DFT1D_Float::DftComplexType* src =
new KK_DFT1D_Float::DftComplexType[numOfBuckets];
1076 for (x = 0; x < numOfBuckets; x++)
1078 kkint32 borderPixelIdx = (
kkint32)(((
double)x * (
double)numOfBorderPixels) / (
double)numOfBuckets);
1080 Point& point = (*points)[borderPixelIdx];
1082 #if defined(FFTW_AVAILABLE) 1083 src[x][0] = (
float)point.Row ();
1084 src[x][1] = (
float)point.Col ();
1086 src[x].real ((
float)point.Row ());
1087 src[x].imag ((
float)point.Col ());
1090 totalRow += point
.Row ();
1091 totalCol += point
.Col ();
1097 float centerRow = (
float)totalRow / (
float)numOfBuckets;
1098 float centerCol = (
float)totalCol / (
float)numOfBuckets;
1100 for (x = 0; x < numOfBuckets; x++)
1102 #if defined(FFTW_AVAILABLE) 1103 src[x][0] = src[x][0] - centerRow;
1104 src[x][1] = src[x][1] - centerCol;
1106 src[x].real (src[x].real () - centerRow);
1107 src[x].imag (src[x].imag () - centerCol);
1111 #if defined(FFTW_AVAILABLE) 1112 fftwf_complex* dest = (fftwf_complex*)fftwf_malloc (
sizeof (fftwf_complex) * numOfBuckets);
1113 fftwf_plan plan = fftwCreateOneDPlan (numOfBuckets, src, dest, FFTW_FORWARD, FFTW_ESTIMATE);
1114 fftwf_execute (plan);
1115 fftwDestroyPlan (plan);
1119 KK_DFT1D_Float::DftComplexType* dest =
new KK_DFT1D_Float::DftComplexType[numOfBuckets];
1120 plan.Transform (src, dest);
1123 for (x = 0; x < numOfBuckets; x++)
1125 #if defined(FFTW_AVAILABLE) 1126 float real = dest[x][0];
1127 float imag = dest[x][1];
1129 float real = dest[x].real ();
1130 float imag = dest[x].imag ();
1133 countourFreq[x] = (
float)(sqrt (real * real + imag * imag));
1136 #if defined(FFTW_AVAILABLE) 1140 delete[] src; src = NULL;
1141 delete[] dest; dest = NULL;
1144 return numOfBorderPixels;
1161 numOfEdgePixels = points->QueueSize ();
1168 for (x = 0; x < numOfBuckets; x++)
1171 float* distances =
new float[points->QueueSize ()];
1173 for (x = 0; x < points->QueueSize (); x++)
1175 Point& point = (*points)[x];
1177 float deltaCol = (
float)point
.Col () - pointCol;
1178 float deltaRow = (
float)point
.Row () - pointRow;
1180 float distance = (
float)sqrt (deltaCol * deltaCol + deltaRow * deltaRow);
1182 distances[x] = distance;
1184 minDistance = Min (minDistance, distance);
1185 maxDistance = Max (maxDistance, distance);
1188 float bucketSize = (maxDistance - minDistance) / numOfBuckets;
1190 if (bucketSize == 0.0)
1192 buckets[numOfBuckets / 2] = points->QueueSize ();
1196 for (x = 0; x < points->QueueSize (); x++)
1198 kkint32 bucketIDX = (
kkint32)((distances[x] - minDistance) / bucketSize);
1199 buckets[bucketIDX]++;
1203 delete points; points = NULL;
1204 delete[] distances; distances = NULL;
1215 #if defined(FFTW_AVAILABLE) 1216 fftw_complex* src = (fftw_complex*)fftw_malloc (
sizeof (fftw_complex) * points.QueueSize ());
1218 KK_DFT1D_Double::DftComplexType* src =
new KK_DFT1D_Double::DftComplexType[points.QueueSize()];
1227 for (x = 0; x < points.QueueSize (); x++)
1229 Point& point (points[x]);
1233 #if defined(FFTW_AVAILABLE) 1234 src[x][0] = (
double)point.Row ();
1235 src[x][1] = (
double)point.Col ();
1237 src[x].real ((
double)point.Row ());
1238 src[x].imag ((
double)point.Col ());
1241 totalRow += point
.Row ();
1242 totalCol += point
.Col ();
1255 #if defined(FFTW_AVAILABLE) 1256 fftw_complex* destFFTW = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * points.QueueSize());
1258 plan = fftw_plan_dft_1d (points.QueueSize (), src, destFFTW, FFTW_FORWARD, FFTW_ESTIMATE);
1259 fftw_execute (plan);
1260 fftw_destroy_plan (plan);
1262 KK_DFT1D_Double::DftComplexType* destFFTW =
new KK_DFT1D_Double::DftComplexType[points.QueueSize()];
1264 plan.Transform (src, destFFTW);
1267 vector<ComplexDouble> dest;
1269 for (
kkint32 l = 0; l < points.QueueSize (); l++)
1271 #if defined(FFTW_AVAILABLE) 1272 dest.push_back (ComplexDouble (destFFTW[l][0] / (
double)(points.QueueSize ()), destFFTW[l][1] / (
double)(points.QueueSize ())));
1274 dest.push_back (ComplexDouble (destFFTW[l].real () / (
double)(points.QueueSize ()), destFFTW[l].imag () / (
double)(points.QueueSize ())));
1291 kkint32 minRow, maxRow, minCol, maxCol;
1296 size_t numOfEdgePixels = origPointList.size ();
1298 #if defined(FFTW_AVAILABLE) 1299 fftw_complex* src = (fftw_complex*)fftw_malloc (
sizeof (fftw_complex) * numOfEdgePixels);
1301 KK_DFT1D_Double::DftComplexType* src =
new KK_DFT1D_Double::DftComplexType[numOfEdgePixels];
1304 for (
kkint32 l = 0; l < (kkint32)fourier.size (); l++)
1306 #if defined(FFTW_AVAILABLE) 1307 src[l][0] = fourier[l].real ();
1308 src[l][1] = fourier[l].imag ();
1310 src[l].real (fourier[l].real());
1311 src[l].imag (fourier[l].imag ());
1315 #if defined(FFTW_AVAILABLE) 1316 fftw_complex* destFFTW = (fftw_complex*)fftw_malloc (
sizeof (fftw_complex) * numOfEdgePixels);
1318 plan = fftw_plan_dft_1d (numOfEdgePixels, src, destFFTW, FFTW_FORWARD, FFTW_ESTIMATE);
1319 fftw_execute (plan);
1320 fftw_destroy_plan (plan);
1322 KK_DFT1D_Double::DftComplexType* destFFTW =
new KK_DFT1D_Double::DftComplexType[numOfEdgePixels];
1324 plan.Transform(src, destFFTW);
1333 for (
kkint32 l = 0; l < (kkint32)fourier.size (); l++)
1336 #if defined(FFTW_AVAILABLE) 1337 double realPart = (
double)destFFTW[l][0];
1338 double imagPart = (
double)destFFTW[l][1];
1339 ComplexDouble z (realPart, imagPart);
1341 double realPart = (
double)destFFTW[l].real ();
1342 double imagPart = (
double)destFFTW[l].imag ();
1349 kkint32 row = (kkint32)(z.real () + 0.5);
1350 if (row > largestRow)
1352 if (row < smallestRow)
1355 kkint32 col = (kkint32)(z.imag () + 0.5);
1356 if (col > largestCol)
1358 if (col < smallestCol)
1362 points->PushOnBack (p);
kkint32 FollowContour2(float *countourFreq, bool &successful)
std::vector< ComplexDouble > CreateFourierFromPointList(const PointList &points)
A class that is used by to represent a single image in memory.
kkint32 CreateFourierDescriptorBySampling(kkint32 numOfBuckets, float *countourFreq, bool &successful)
float CalcMagnitude(KK_DFT1D_Float::DftComplexType *dest, kkint32 index)
Used by Raster class and MorphOp derived classes to denote a single pixel location in Raster image...
KK_DFT1D< double > KK_DFT1D_Double
std::complex< double > ComplexDouble
KK_DFT1D< float > KK_DFT1D_Float
ComplexDouble ** GetRevFourierOneDimMask(kkint32 size)
unsigned char uchar
Unsigned character.
ComplexDouble ** GetFourierOneDimMask(kkint32 size)
uchar BackgroundPixelTH() const
Point(kkint32 _row, kkint32 _col)
void HistogramDistanceFromAPointOfEdge(float pointRow, float pointCol, kkint32 numOfBuckets, kkint32 *buckets, float &minDistance, float &maxDistance, kkint32 &numOfEdgePixels)
ContourFollower(Raster &_raster, RunLog &_log)
Used for logging messages.
Container object used to maintaining a list of pixel locations.
kkint32 FollowContour(float *countourFreq, float fourierDescriptors[15], kkint32 totalPixels, bool &successful)
void BoxCoordinites(kkint32 &minRow, kkint32 &minCol, kkint32 &maxRow, kkint32 &maxCol)
PointListPtr GenerateContourList()
const MovDir movements[8]
PointListPtr CreatePointListFromFourier(std::vector< ComplexDouble > fourier, PointList &origPointList)