37 #include "segm/msImageProcessor.h"
64 msImageProcessor::msImageProcessor(
void )
80 modePointCounts = NULL;
104 class_state.OUTPUT_DEFINED =
false;
118 msImageProcessor::~msImageProcessor(
void )
122 if(class_state.OUTPUT_DEFINED) DestroyOutput();
123 if(regionList)
delete regionList;
156 void msImageProcessor::DefineImage(
byte *data_, imageType type,
int height_,
int width_)
168 float *luv =
new float [height_*width_*dim];
171 for(i = 0; i < height_*width_; i++)
172 luv[i] = (
float)(data_[i]);
176 for(i = 0; i < height_*width_; i++)
178 RGBtoLUV(&data_[dim*i], &luv[dim*i]);
183 DefineLInput(luv, height_, width_, dim);
190 kernelType k[2] = {Uniform, Uniform};
192 float tempH[2] = {1.0 , 1.0};
195 DefineKernel(k, tempH, P, 2);
206 void msImageProcessor::DefineBgImage(
byte* data_, imageType type,
int height_,
int width_)
219 float *luv =
new float [height_*width_*dim];
223 for(i = 0; i < height_*width_; i++)
224 luv[i] = (
float)(data_[i]);
228 for(i = 0; i < height_*width_; i++)
229 RGBtoLUV(&data_[dim*i], &luv[dim*i]);
234 DefineLInput(luv, height_, width_, dim);
242 kernelType k[2] = {Uniform, Uniform};
244 float tempH[2] = {1.0 , 1.0};
247 DefineKernel(k, tempH, P, 2);
281 void msImageProcessor::SetWeightMap(
float *wm,
float eps)
285 SetLatticeWeightMap(wm);
288 if((epsilon = eps) < 0)
289 ErrorHandler(
"msImageProcessor",
"SetWeightMap",
"Threshold is negative.");
307 void msImageProcessor::RemoveWeightMap(
void )
311 RemoveLatticeWeightMap();
351 void msImageProcessor::Filter(
int sigmaS,
float sigmaR, SpeedUpLevel speedUpLevel)
363 classConsistencyCheck(N+2,
true);
364 if(ErrorStatus == EL_ERROR)
368 if((ErrorStatus = msSys.Progress((
float)(0.0))) == EL_HALT)
376 if(class_state.OUTPUT_DEFINED ==
false)
381 if(ErrorStatus == EL_ERROR)
388 if((!(modeTable =
new unsigned char [L]))||(!(pointList =
new int [L])))
390 ErrorHandler(
"msImageProcessor",
"Allocate",
"Not enough memory.");
408 NewNonOptimizedFilter((
float)(sigmaS), sigmaR);
413 NewOptimizedFilter1((
float)(sigmaS), sigmaR);
418 NewOptimizedFilter2((
float)(sigmaS), sigmaR);
438 if((ErrorStatus = msSys.Progress((
float)(0.8))) == EL_HALT)
461 for (i=0; i<L*N; i++)
463 LUV_data[i] = msRawData[i];
468 timer = msSys.ElapsedTime();
469 msSys.Prompt(
"(%6.2f sec)\nConnecting regions ...", timer);
477 timer = msSys.ElapsedTime();
478 msSys.Prompt(
"done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
513 void msImageProcessor::FuseRegions(
float sigmaS,
int minRegion)
525 classConsistencyCheck(N+2,
true);
526 if(ErrorStatus == EL_ERROR)
531 if((ErrorStatus = msSys.Progress((
float)(0.8))) == EL_HALT)
533 if(class_state.OUTPUT_DEFINED) DestroyOutput();
539 if((h[1] = sigmaS) <= 0)
541 ErrorHandler(
"msImageProcessor",
"FuseRegions",
"The feature radius must be greater than or equal to zero.");
547 if(!(class_state.OUTPUT_DEFINED))
555 if(ErrorStatus == EL_ERROR)
571 for (i=0; i<L*N; i++)
573 LUV_data[i] = data[i];
577 msSys.Prompt(
"Connecting regions ...");
585 if(ErrorStatus == EL_ERROR)
589 double timer = msSys.ElapsedTime();
590 msSys.Prompt(
"done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
597 if((ErrorStatus = msSys.Progress((
float)(0.85))) == EL_HALT)
604 msSys.Prompt(
"Applying transitive closure...");
609 visitTable =
new unsigned char [L];
614 rR2 = (float)(h[1]*h[1]*0.25);
616 int oldRC = regionCount;
617 int deltaRC, counter = 0;
620 deltaRC = oldRC-regionCount;
623 }
while ((deltaRC <= 0)&&(counter < 10));
626 delete [] visitTable;
631 if((ErrorStatus = msSys.Progress((
float)(1.0))) == EL_HALT)
639 double timer = msSys.ElapsedTime();
640 msSys.Prompt(
"done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions ...", timer, regionCount);
649 timer = msSys.ElapsedTime();
650 msSys.Prompt(
"done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
656 if((ErrorStatus = msSys.Progress((
float)(1.0))) == EL_HALT)
668 for(i = 0; i < L; i++)
671 for(j = 0; j < N; j++)
673 msRawData[N*i+j] = modes[N*label+j];
712 void msImageProcessor::Segment(
int sigmaS,
float sigmaR,
int minRegion, SpeedUpLevel speedUpLevel)
718 ErrorHandler(
"msImageProcessor",
"Segment",
"Kernel corrupt or undefined.");
723 Filter(sigmaS, sigmaR, speedUpLevel);
726 if(ErrorStatus == EL_ERROR)
730 if(ErrorStatus == EL_HALT)
735 if((ErrorStatus = msSys.Progress((
float)(0.85))) == EL_HALT)
742 msSys.Prompt(
"Applying transitive closure...");
747 visitTable =
new unsigned char [L];
752 rR2 = (float)(h[1]*h[1]*0.25);
754 int oldRC = regionCount;
755 int deltaRC, counter = 0;
758 deltaRC = oldRC-regionCount;
761 }
while ((deltaRC <= 0)&&(counter < 10));
764 delete [] visitTable;
769 if((ErrorStatus = msSys.Progress((
float)(0.95))) == EL_HALT)
777 double timer = msSys.ElapsedTime();
778 msSys.Prompt(
"done. (%6.2f seconds, numRegions = %6d).\nPruning spurious regions\t... ", timer, regionCount);
787 timer = msSys.ElapsedTime();
788 msSys.Prompt(
"done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions ...", timer, regionCount);
794 if((ErrorStatus = msSys.Progress(1.0)) == EL_HALT)
806 for(i = 0; i < L; i++)
809 for(j = 0; j < N; j++)
811 msRawData[N*i+j] = modes[N*label+j];
844 void msImageProcessor::RGBtoLUV(
byte *rgbVal,
float *luvVal)
848 double x, y, z, L0, u_prime, v_prime, constant;
851 x = XYZ[0][0]*rgbVal[0] + XYZ[0][1]*rgbVal[1] + XYZ[0][2]*rgbVal[2];
852 y = XYZ[1][0]*rgbVal[0] + XYZ[1][1]*rgbVal[1] + XYZ[1][2]*rgbVal[2];
853 z = XYZ[2][0]*rgbVal[0] + XYZ[2][1]*rgbVal[1] + XYZ[2][2]*rgbVal[2];
858 L0 = y / (255.0 * Yn);
860 luvVal[0] = (float)(116.0 * (pow(L0, 1.0/3.0)) - 16.0);
862 luvVal[0] = (float)(903.3 * L0);
865 constant = x + 15 * y + 3 * z;
868 u_prime = (4 * x) / constant;
869 v_prime = (9 * y) / constant;
878 luvVal[1] = (float) (13 * luvVal[0] * (u_prime - Un_prime));
879 luvVal[2] = (float) (13 * luvVal[0] * (v_prime - Vn_prime));
902 inline int my_round(
double in_x)
905 return (
int)(in_x - 0.5);
907 return (
int)(in_x + 0.5);
910 void msImageProcessor::LUVtoRGB(
float *luvVal,
byte *rgbVal)
915 double x, y, z, u_prime, v_prime;
924 y = Yn * luvVal[0] / 903.3;
927 y = (luvVal[0] + 16.0) / 116.0;
931 u_prime = luvVal[1] / (13 * luvVal[0]) + Un_prime;
932 v_prime = luvVal[2] / (13 * luvVal[0]) + Vn_prime;
934 x = 9 * u_prime * y / (4 * v_prime);
935 z = (12 - 3 * u_prime - 20 * v_prime) * y / (4 * v_prime);
939 r = my_round((RGB[0][0]*x + RGB[0][1]*y + RGB[0][2]*z)*255.0);
940 g = my_round((RGB[1][0]*x + RGB[1][1]*y + RGB[1][2]*z)*255.0);
941 b = my_round((RGB[2][0]*x + RGB[2][1]*y + RGB[2][2]*z)*255.0);
944 if(r < 0) r = 0;
if(r > 255) r = 255;
945 if(g < 0) g = 0;
if(g > 255) g = 255;
946 if(b < 0) b = 0;
if(b > 255) b = 255;
978 void msImageProcessor::GetRawData(
float *outputImageData)
983 ErrorHandler(
"msImageProcessor",
"GetRawData",
"Output image data buffer is NULL.");
989 for(i = 0; i < L*N; i++)
990 outputImageData[i] = msRawData[i];
1010 void msImageProcessor::GetResults(
byte *outputImage)
1016 ErrorHandler(
"msImageProcessor",
"GetResults",
"Output image buffer is NULL.");
1027 for(i = 0; i < L; i++)
1031 pxValue = (int)(msRawData[i]+0.5);
1035 outputImage[i] = (byte)(0);
1036 else if(pxValue > 255)
1037 outputImage[i] = (byte)(255);
1039 outputImage[i] = (byte)(pxValue);
1050 for(i = 0; i < L; i++)
1051 LUVtoRGB(&msRawData[N*i], &outputImage[N*i]);
1056 ErrorHandler(
"msImageProcessor",
"GetResults",
"Unknown image type. Try using MeanShift::GetRawData().");
1077 RegionList *msImageProcessor::GetBoundaries(
void )
1081 if(class_state.OUTPUT_DEFINED)
1120 int msImageProcessor::GetRegions(
int **labels_out,
float **modes_out,
int **MPC_out)
1123 if(class_state.OUTPUT_DEFINED ==
false)
1138 if(!(labels_ =
new int [L]))
1140 ErrorHandler(
"msImageProcessor",
"GetRegions",
"Not enough memory.");
1143 if(!(modes_ =
new float [regionCount*N]))
1145 ErrorHandler(
"msImageProcessor",
"GetRegions",
"Not enough memory.");
1148 if(!(MPC_out_ =
new int [regionCount]))
1150 ErrorHandler(
"msImageProcessor",
"GetRegions",
"Not enough memory.");
1156 for(i = 0; i < L; i++)
1157 labels_[i] = labels[i];
1161 for(i = 0; i < regionCount*N; i++)
1162 modes_[i] = modes[i];
1163 for(i = 0; i < regionCount; i++)
1164 MPC_out_[i] = modePointCounts[i];
1170 *labels_out = labels;
1172 *modes_out = modes_;
1174 *MPC_out = MPC_out_;
1213 void msImageProcessor::NonOptimizedFilter(
float sigmaS,
float sigmaR)
1217 int iterationCount, i, j;
1224 ErrorHandler(
"msImageProcessor",
"LFilter",
"Lattice height and width are undefined.");
1229 if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
1231 ErrorHandler(
"msImageProcessor",
"Segment",
"sigmaS and/or sigmaR is zero or negative.");
1242 double *yk =
new double [lN];
1245 double *Mh =
new double [lN];
1249 msSys.Prompt(
"done.\nApplying mean shift (Using Lattice)... ");
1250 #ifdef SHOW_PROGRESS
1251 msSys.Prompt(
"\n 0%%");
1255 for(i = 0; i < L; i++)
1263 for(j = 0; j < N; j++)
1264 yk[j+2] = data[N*i+j];
1267 LatticeMSVector(Mh, yk);
1271 for(j = 0; j < lN; j++)
1272 mvAbs += Mh[j]*Mh[j];
1281 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
1285 for(j = 0; j < lN; j++)
1290 LatticeMSVector(Mh, yk);
1294 for(j = 0; j < lN; j++)
1295 mvAbs += Mh[j]*Mh[j];
1303 for(j = 0; j < lN; j++)
1307 for(j = 0; j < N; j++)
1308 msRawData[N*i+j] = (
float)(yk[j+2]);
1311 #ifdef SHOW_PROGRESS
1312 percent_complete = (float)(i/(
float)(L))*100;
1313 msSys.Prompt(
"\r%2d%%", (
int)(percent_complete + 0.5));
1317 if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((
float)(i/(float)(L))*(
float)(0.8)))) == EL_HALT)
1323 #ifdef SHOW_PROGRESS
1326 msSys.Prompt(
"done.");
1363 void msImageProcessor::OptimizedFilter1(
float sigmaS,
float sigmaR)
1367 int iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i;
1368 float *modeCandidatePoint;
1369 double mvAbs, diff, el;
1375 ErrorHandler(
"msImageProcessor",
"LFilter",
"Lattice height and width are undefined.");
1380 if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
1382 ErrorHandler(
"msImageProcessor",
"Segment",
"sigmaS and/or sigmaR is zero or negative.");
1393 double *yk =
new double [lN];
1396 double *Mh =
new double [lN];
1399 memset(modeTable, 0, width*height);
1403 modeCandidatePoint =
new float [N];
1407 msSys.Prompt(
"done.\nApplying mean shift (Using Lattice) ... ");
1408 #ifdef SHOW_PROGRESS
1409 msSys.Prompt(
"\n 0%%");
1414 for(i = 0; i < L; i++)
1419 if (modeTable[i] == 1)
1430 for(j = 0; j < N; j++)
1431 yk[j+2] = data[N*i+j];
1434 LatticeMSVector(Mh, yk);
1438 for(j = 0; j < lN; j++)
1439 mvAbs += Mh[j]*Mh[j];
1448 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
1452 for(j = 0; j < lN; j++)
1459 modeCandidateX = (int) (yk[0]+0.5);
1460 modeCandidateY = (int) (yk[1]+0.5);
1461 modeCandidate_i = modeCandidateY*width + modeCandidateX;
1476 if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
1481 for (j = 0; j < N; j++)
1482 modeCandidatePoint[j] = data[N*modeCandidate_i + j];
1488 while ((diff < TC_DIST_FACTOR) && (k<kp))
1491 for (p=0; p<P[k]; p++)
1493 el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k];
1504 if (diff < TC_DIST_FACTOR)
1510 if (modeTable[modeCandidate_i] == 0)
1514 pointList[pointCount++] = modeCandidate_i;
1515 modeTable[modeCandidate_i] = 2;
1526 for (j = 0; j < N; j++)
1527 yk[j+2] = msRawData[modeCandidate_i*N+j];
1546 LatticeMSVector(Mh, yk);
1550 for(j = 0; j < lN; j++)
1551 mvAbs += Mh[j]*Mh[j];
1563 for(j = 0; j < lN; j++)
1575 for (j = 0; j < pointCount; j++)
1579 modeCandidate_i = pointList[j];
1582 modeTable[modeCandidate_i] = 1;
1585 for(k = 0; k < N; k++)
1586 msRawData[N*modeCandidate_i+k] = (
float)(yk[k+2]);
1591 for(j = 0; j < N; j++)
1592 msRawData[N*i+j] = (
float)(yk[j+2]);
1595 #ifdef SHOW_PROGRESS
1596 percent_complete = (float)(i/(
float)(L))*100;
1597 msSys.Prompt(
"\r%2d%%", (
int)(percent_complete + 0.5));
1601 if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((
float)(i/(float)(L))*(
float)(0.8)))) == EL_HALT)
1607 #ifdef SHOW_PROGRESS
1610 msSys.Prompt(
"done.");
1614 delete [] modeCandidatePoint;
1650 void msImageProcessor::OptimizedFilter2(
float sigmaS,
float sigmaR)
1656 weightMap =
new float [L];
1658 for(i = 0; i < L; i++)
1663 int iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i;
1664 float *modeCandidatePoint;
1665 double mvAbs, diff, el;
1671 ErrorHandler(
"msImageProcessor",
"LFilter",
"Lattice height and width are undefined.");
1676 if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
1678 ErrorHandler(
"msImageProcessor",
"Segment",
"sigmaS and/or sigmaR is zero or negative.");
1689 double *yk =
new double [lN];
1692 double *Mh =
new double [lN];
1695 memset(modeTable, 0, width*height);
1699 modeCandidatePoint =
new float [N];
1703 msSys.Prompt(
"done.\nApplying mean shift (Using Lattice)... ");
1704 #ifdef SHOW_PROGRESS
1705 msSys.Prompt(
"\n 0%%");
1709 for(i = 0; i < L; i++)
1714 if (modeTable[i] == 1)
1725 for(j = 0; j < N; j++)
1726 yk[j+2] = data[N*i+j];
1729 OptLatticeMSVector(Mh, yk);
1733 for(j = 0; j < lN; j++)
1734 mvAbs += Mh[j]*Mh[j];
1743 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
1747 for(j = 0; j < lN; j++)
1754 modeCandidateX = (int) (yk[0]+0.5);
1755 modeCandidateY = (int) (yk[1]+0.5);
1756 modeCandidate_i = modeCandidateY*width + modeCandidateX;
1771 if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
1776 for (j = 0; j < N; j++)
1777 modeCandidatePoint[j] = data[N*modeCandidate_i + j];
1783 while ((diff < TC_DIST_FACTOR) && (k<kp))
1786 for (p=0; p<P[k]; p++)
1788 el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k];
1799 if (diff < TC_DIST_FACTOR)
1805 if (modeTable[modeCandidate_i] == 0)
1809 pointList[pointCount++] = modeCandidate_i;
1810 modeTable[modeCandidate_i] = 2;
1821 for (j = 0; j < N; j++)
1822 yk[j+2] = msRawData[modeCandidate_i*N+j];
1841 OptLatticeMSVector(Mh, yk);
1845 for(j = 0; j < lN; j++)
1846 mvAbs += Mh[j]*Mh[j];
1859 for(j = 0; j < lN; j++)
1871 for (j = 0; j < pointCount; j++)
1875 modeCandidate_i = pointList[j];
1878 modeTable[modeCandidate_i] = 1;
1881 for(k = 0; k < N; k++)
1882 msRawData[N*modeCandidate_i+k] = (
float)(yk[k+2]);
1887 for(j = 0; j < N; j++)
1888 msRawData[N*i+j] = (
float)(yk[j+2]);
1891 #ifdef SHOW_PROGRESS
1892 percent_complete = (float)(i/(
float)(L))*100;
1893 msSys.Prompt(
"\r%2d%%", (
int)(percent_complete + 0.5));
1897 if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((
float)(i/(float)(L))*(
float)(0.8)))) == EL_HALT)
1904 #ifdef SHOW_PROGRESS
1907 msSys.Prompt(
"done.");
1911 delete [] modeCandidatePoint;
1940 void msImageProcessor::Connect(
void )
1947 neigh[3] = -(1+width);
1955 for(i = 0; i < width*height; i++)
1958 modePointCounts[i] = 0;
1963 for(i = 0; i < height*width; i++)
1969 labels[i] = ++label;
1972 for(k = 0; k < N; k++)
1973 modes[(N*label)+k] = LUV_data[(N*i)+k];
1983 regionCount = label+1;
2011 void msImageProcessor::Fill(
int regionLoc,
int label)
2015 int i, k, neighLoc, neighborsFound, imageSize = width*height;
2022 indexTable[0] = regionLoc;
2026 modePointCounts[label]++;
2037 for(i = 0; i < 8; i++)
2050 neighLoc = regionLoc + neigh[i];
2051 if((neighLoc >= 0)&&(neighLoc < imageSize)&&(labels[neighLoc] < 0))
2053 for(k = 0; k < N; k++)
2056 if (fabs(LUV_data[(regionLoc*N)+k]-LUV_data[(neighLoc*N)+k])>=LUV_treshold)
2066 labels[neighLoc] = label;
2069 modePointCounts[label]++;
2072 indexTable[++index] = neighLoc;
2085 regionLoc = indexTable[index];
2087 regionLoc = indexTable[--index];
2114 void msImageProcessor::BuildRAM(
void )
2118 if((!raList)&&((!(raList =
new RAList [regionCount]))||(!(raPool =
new RAList [NODE_MULTIPLE*regionCount]))))
2120 ErrorHandler(
"msImageProcessor",
"Allocate",
"Not enough memory.");
2126 for(i = 0; i < regionCount; i++)
2128 raList[i].edgeStrength = 0;
2129 raList[i].edgePixelCount = 0;
2130 raList[i].label = i;
2131 raList[i].next = NULL;
2135 freeRAList = raPool;
2136 for(i = 0; i < NODE_MULTIPLE*regionCount-1; i++)
2138 raPool[i].edgeStrength = 0;
2139 raPool[i].edgePixelCount = 0;
2140 raPool[i].next = &raPool[i+1];
2142 raPool[NODE_MULTIPLE*regionCount-1].next = NULL;
2149 int j, curLabel, rightLabel, bottomLabel, exists;
2150 RAList *raNode1, *raNode2, *oldRAFreeList;
2151 for(i = 0; i < height - 1; i++)
2155 for(j = 0; j < width - 1; j++)
2158 curLabel = labels[i*width+j ];
2159 rightLabel = labels[i*width+j+1 ];
2160 bottomLabel = labels[(i+1)*width+j];
2166 if(curLabel != rightLabel)
2170 raNode1 = freeRAList;
2171 raNode2 = freeRAList->next;
2176 oldRAFreeList = freeRAList;
2179 freeRAList = freeRAList->next->next;
2182 raNode1->label = curLabel;
2183 raNode2->label = rightLabel;
2187 raList[curLabel ].Insert(raNode2);
2188 exists = raList[rightLabel].Insert(raNode1);
2194 freeRAList = oldRAFreeList;
2202 if(curLabel != bottomLabel)
2206 raNode1 = freeRAList;
2207 raNode2 = freeRAList->next;
2212 oldRAFreeList = freeRAList;
2215 freeRAList = freeRAList->next->next;
2218 raNode1->label = curLabel;
2219 raNode2->label = bottomLabel;
2223 raList[curLabel ].Insert(raNode2);
2224 exists = raList[bottomLabel].Insert(raNode1);
2230 freeRAList = oldRAFreeList;
2240 curLabel = labels[i*width+j ];
2241 bottomLabel = labels[(i+1)*width+j];
2247 if(curLabel != bottomLabel)
2251 raNode1 = freeRAList;
2252 raNode2 = freeRAList->next;
2257 oldRAFreeList = freeRAList;
2260 freeRAList = freeRAList->next->next;
2263 raNode1->label = curLabel;
2264 raNode2->label = bottomLabel;
2268 raList[curLabel ].Insert(raNode2);
2269 exists = raList[bottomLabel].Insert(raNode1);
2275 freeRAList = oldRAFreeList;
2284 for(j = 0; j < width - 1; j++)
2287 curLabel = labels[i*width+j ];
2288 rightLabel = labels[i*width+j+1 ];
2294 if(curLabel != rightLabel)
2298 raNode1 = freeRAList;
2299 raNode2 = freeRAList->next;
2304 oldRAFreeList = freeRAList;
2307 freeRAList = freeRAList->next->next;
2310 raNode1->label = curLabel;
2311 raNode2->label = rightLabel;
2315 raList[curLabel ].Insert(raNode2);
2316 exists = raList[rightLabel].Insert(raNode1);
2322 freeRAList = oldRAFreeList;
2345 void msImageProcessor::DestroyRAM(
void )
2349 if (raList)
delete [] raList;
2350 if (raPool)
delete [] raPool;
2378 void msImageProcessor::TransitiveClosure(
void )
2390 if(weightMapDefined) ComputeEdgeStrengths();
2405 int i, iCanEl, neighCanEl;
2408 for(i = 0; i < regionCount; i++)
2412 neighbor = raList[i].next;
2416 if(epsilon > raList[i].edgeStrength)
2417 threshold = epsilon;
2419 threshold = raList[i].edgeStrength;
2427 if((InWindow(i, neighbor->label))&&(neighbor->edgeStrength < epsilon))
2434 while(raList[iCanEl].label != iCanEl)
2435 iCanEl = raList[iCanEl].label;
2438 neighCanEl = neighbor->label;
2439 while(raList[neighCanEl].label != neighCanEl)
2440 neighCanEl = raList[neighCanEl].label;
2445 if(iCanEl < neighCanEl)
2446 raList[neighCanEl].label = iCanEl;
2451 raList[raList[iCanEl].label].label = neighCanEl;
2454 raList[iCanEl].label = neighCanEl;
2459 neighbor = neighbor->next;
2467 for(i = 0; i < regionCount; i++)
2470 while(raList[iCanEl].label != iCanEl)
2471 iCanEl = raList[iCanEl].label;
2472 raList[i].label = iCanEl;
2485 float *modes_buffer =
new float [N*regionCount];
2486 int *MPC_buffer =
new int [regionCount];
2489 for(i = 0; i < regionCount; i++)
2491 for(i = 0; i < N*regionCount; i++)
2492 modes_buffer[i] = 0;
2497 for(i = 0; i < regionCount; i++)
2501 iCanEl = raList[i].label;
2504 iMPC = modePointCounts[i];
2507 for(k = 0; k < N; k++)
2508 modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k];
2511 MPC_buffer[iCanEl] += iMPC;
2525 int *label_buffer =
new int [regionCount];
2528 for(i = 0; i < regionCount; i++)
2529 label_buffer[i] = -1;
2533 for(i = 0; i < regionCount; i++)
2536 iCanEl = raList[i].label;
2537 if(label_buffer[iCanEl] < 0)
2541 label_buffer[iCanEl] = ++label;
2544 iMPC = MPC_buffer[iCanEl];
2545 for(k = 0; k < N; k++)
2546 modes[(N*label)+k] = (modes_buffer[(N*iCanEl)+k])/(iMPC);
2550 modePointCounts[label] = MPC_buffer[iCanEl];
2555 int oldRegionCount = regionCount;
2556 regionCount = label+1;
2563 for(i = 0; i < height*width; i++)
2564 labels[i] = label_buffer[raList[labels[i]].label];
2567 delete [] modes_buffer;
2568 delete [] MPC_buffer;
2569 delete [] label_buffer;
2592 void msImageProcessor::ComputeEdgeStrengths(
void )
2599 memset(visitTable, 0, L*
sizeof(
unsigned char));
2603 int x, y, dp, curLabel, rightLabel, bottomLabel;
2605 for(y = 1; y < height-1; y++)
2607 for(x = 1; x < width-1; x++)
2613 curLabel = labels[dp ];
2614 rightLabel = labels[dp+1 ];
2615 bottomLabel = labels[dp+width];
2621 if(curLabel != rightLabel)
2624 curRegion = &raList[curLabel];
2625 while((curRegion)&&(curRegion->label != rightLabel))
2626 curRegion = curRegion->next;
2632 curRegion->edgeStrength += weightMap[dp] + weightMap[dp+1];
2633 curRegion->edgePixelCount += 2;
2636 if(curLabel != bottomLabel)
2639 curRegion = &raList[curLabel];
2640 while((curRegion)&&(curRegion->label != bottomLabel))
2641 curRegion = curRegion->next;
2647 if(curLabel == rightLabel)
2649 curRegion->edgeStrength += weightMap[dp] + weightMap[dp+width];
2650 curRegion->edgePixelCount += 2;
2654 curRegion->edgeStrength += weightMap[dp+width];
2655 curRegion->edgePixelCount += 1;
2663 RAList *neighborRegion;
2666 for(x = 0; x < regionCount; x++)
2669 curRegion = &raList[x];
2670 curRegion = curRegion->next;
2679 curLabel = curRegion->label;
2684 neighborRegion = &raList[curLabel];
2685 while((neighborRegion)&&(neighborRegion->label != x))
2686 neighborRegion = neighborRegion->next;
2689 assert(neighborRegion);
2693 if((edgePixelCount = curRegion->edgePixelCount + neighborRegion->edgePixelCount) != 0)
2696 edgeStrength = curRegion->edgeStrength + neighborRegion->edgeStrength;
2697 edgeStrength /= edgePixelCount;
2700 curRegion->edgeStrength = neighborRegion->edgeStrength = edgeStrength;
2701 curRegion->edgePixelCount = neighborRegion->edgePixelCount = edgePixelCount;
2707 curRegion = curRegion->next;
2715 for(x = 0; x < regionCount; x++)
2719 curRegion = &raList[x];
2720 curRegion = curRegion->next;
2726 edgeStrength += curRegion->edgeStrength;
2727 curRegion = curRegion->next;
2732 if(numNeighbors) edgeStrength /= numNeighbors;
2736 raList[x].edgeStrength = edgeStrength;
2763 void msImageProcessor::Prune(
int minRegion)
2769 float *modes_buffer =
new float [N*regionCount];
2770 int *MPC_buffer =
new int [regionCount];
2773 int *label_buffer =
new int [regionCount];
2776 int i, k, candidate, iCanEl, neighCanEl, iMPC, label, oldRegionCount, minRegionCount;
2777 double minSqDistance, neighborDistance;
2806 for(i = 0; i < regionCount; i++)
2821 if(modePointCounts[i] < minRegion)
2829 neighbor = raList[i].next;
2833 candidate = neighbor->label;
2834 minSqDistance = SqDistance(i, candidate);
2838 neighbor = neighbor->next;
2844 neighborDistance = SqDistance(i, neighbor->label);
2849 if(neighborDistance < minSqDistance)
2851 minSqDistance = neighborDistance;
2852 candidate = neighbor->label;
2856 neighbor = neighbor->next;
2864 while(raList[iCanEl].label != iCanEl)
2865 iCanEl = raList[iCanEl].label;
2868 neighCanEl = candidate;
2869 while(raList[neighCanEl].label != neighCanEl)
2870 neighCanEl = raList[neighCanEl].label;
2875 if(iCanEl < neighCanEl)
2876 raList[neighCanEl].label = iCanEl;
2881 raList[raList[iCanEl].label].label = neighCanEl;
2884 raList[iCanEl].label = neighCanEl;
2892 for(i = 0; i < regionCount; i++)
2895 while(raList[iCanEl].label != iCanEl)
2896 iCanEl = raList[iCanEl].label;
2897 raList[i].label = iCanEl;
2908 for(i = 0; i < regionCount; i++)
2910 for(i = 0; i < N*regionCount; i++)
2911 modes_buffer[i] = 0;
2915 for(i = 0; i < regionCount; i++)
2919 iCanEl = raList[i].label;
2922 iMPC = modePointCounts[i];
2925 for(k = 0; k < N; k++)
2926 modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k];
2929 MPC_buffer[iCanEl] += iMPC;
2943 for(i = 0; i < regionCount; i++)
2944 label_buffer[i] = -1;
2948 for(i = 0; i < regionCount; i++)
2951 iCanEl = raList[i].label;
2952 if(label_buffer[iCanEl] < 0)
2956 label_buffer[iCanEl] = ++label;
2959 iMPC = MPC_buffer[iCanEl];
2960 for(k = 0; k < N; k++)
2961 modes[(N*label)+k] = (modes_buffer[(N*iCanEl)+k])/(iMPC);
2965 modePointCounts[label] = MPC_buffer[iCanEl];
2970 oldRegionCount = regionCount;
2971 regionCount = label+1;
2978 for(i = 0; i < height*width; i++)
2979 labels[i] = label_buffer[raList[labels[i]].label];
2982 }
while(minRegionCount > 0);
2985 delete [] modes_buffer;
2986 delete [] MPC_buffer;
2987 delete [] label_buffer;
3012 void msImageProcessor::DefineBoundaries(
void )
3016 int *boundaryMap, *boundaryCount;
3017 if((!(boundaryMap =
new int [L]))||(!(boundaryCount =
new int [regionCount])))
3018 ErrorHandler(
"msImageProcessor",
"DefineBoundaries",
"Not enough memory.");
3022 for(i = 0; i < L; i++)
3023 boundaryMap[i] = -1;
3024 for(i = 0; i < regionCount; i++)
3025 boundaryCount[i] = 0;
3030 int totalBoundaryCount = 0;
3040 int j, label, dataPoint;
3043 for(i = 0; i < width; i++)
3045 boundaryMap[i] = label = labels[i];
3046 boundaryCount[label]++;
3047 totalBoundaryCount++;
3052 for(i = 1; i < height - 1; i++)
3055 dataPoint = i*width;
3056 boundaryMap[dataPoint] = label = labels[dataPoint];
3057 boundaryCount[label]++;
3058 totalBoundaryCount++;
3060 for(j = 1; j < width - 1; j++)
3064 dataPoint = i*width+j;
3068 label = labels[dataPoint];
3069 if((label != labels[dataPoint-1]) ||(label != labels[dataPoint+1])||
3070 (label != labels[dataPoint-width])||(label != labels[dataPoint+width]))
3072 boundaryMap[dataPoint] = label = labels[dataPoint];
3073 boundaryCount[label]++;
3074 totalBoundaryCount++;
3079 dataPoint = (i+1)*width-1;
3080 boundaryMap[dataPoint] = label = labels[dataPoint];
3081 boundaryCount[label]++;
3082 totalBoundaryCount++;
3087 register int start = (height-1)*width, stop = height*width;
3088 for(i = start; i < stop; i++)
3090 boundaryMap[i] = label = labels[i];
3091 boundaryCount[label]++;
3092 totalBoundaryCount++;
3104 int *boundaryBuffer =
new int [totalBoundaryCount], *boundaryIndex =
new int [regionCount];
3108 for(i = 0; i < regionCount; i++)
3110 boundaryIndex[i] = counter;
3111 counter += boundaryCount[i];
3116 for(i = 0; i < L; i++)
3120 if((label = boundaryMap[i]) >= 0)
3122 boundaryBuffer[boundaryIndex[label]] = i;
3123 boundaryIndex[label]++;
3137 if(regionList)
delete regionList;
3140 if(!(regionList =
new RegionList(regionCount, totalBoundaryCount, N)))
3141 ErrorHandler(
"msImageProcessor",
"DefineBoundaries",
"Not enough memory.");
3146 for(i = 0; i < regionCount; i++)
3148 regionList->AddRegion(i, boundaryCount[i], &boundaryBuffer[counter]);
3149 counter += boundaryCount[i];
3156 delete [] boundaryMap;
3157 delete [] boundaryCount;
3158 delete [] boundaryBuffer;
3159 delete [] boundaryIndex;
3186 bool msImageProcessor::InWindow(
int mode1,
int mode2)
3188 int k = 1, s = 0, p;
3189 double diff = 0, el;
3190 while((diff < 0.25)&&(k != kp))
3194 for(p = 0; p < P[k]; p++)
3196 el = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]);
3197 if((!p)&&(k == 1)&&(modes[mode1*N] > 80))
3207 return (
bool)(diff < 0.25);
3225 float msImageProcessor::SqDistance(
int mode1,
int mode2)
3228 int k = 1, s = 0, p;
3230 for(k = 1; k < kp; k++)
3233 for(p = 0; p < P[k]; p++)
3235 el = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]);
3266 void msImageProcessor::InitializeOutput(
void )
3273 if(!(msRawData =
new float [L*N]))
3275 ErrorHandler(
"msImageProcessor",
"Allocate",
"Not enough memory.");
3280 if((!(modes =
new float [L*(N+2)]))||(!(labels =
new int [L]))||(!(modePointCounts =
new int [L]))||(!(indexTable =
new int [L])))
3282 ErrorHandler(
"msImageProcessor",
"Allocate",
"Not enough memory");
3289 if (!(LUV_data =
new float[N*L]))
3291 ErrorHandler(
"msImageProcessor",
"Allocate",
"Not enough memory");
3296 class_state.OUTPUT_DEFINED =
true;
3314 void msImageProcessor::DestroyOutput(
void )
3318 if (msRawData)
delete [] msRawData;
3322 if (modes)
delete [] modes;
3323 if (labels)
delete [] labels;
3324 if (modePointCounts)
delete [] modePointCounts;
3325 if (indexTable)
delete [] indexTable;
3328 if (LUV_data)
delete [] LUV_data;
3338 modePointCounts = NULL;
3342 class_state.OUTPUT_DEFINED =
false;
3350 void msImageProcessor::NewOptimizedFilter1(
float sigmaS,
float sigmaR)
3353 int iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i;
3354 double mvAbs, diff, el;
3360 ErrorHandler(
"msImageProcessor",
"LFilter",
"Lattice height and width are undefined.");
3365 if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
3367 ErrorHandler(
"msImageProcessor",
"Segment",
"sigmaS and/or sigmaR is zero or negative.");
3378 double *yk =
new double [lN];
3381 double *Mh =
new double [lN];
3385 sdata =
new float[lN*L];
3394 sdata[idxs++] = (i%width)/sigmaS;
3395 sdata[idxs++] = (i/width)/sigmaS;
3396 sdata[idxs++] = data[idxd++]/sigmaR;
3397 sdata[idxs++] = data[idxd++]/sigmaR;
3398 sdata[idxs++] = data[idxd++]/sigmaR;
3404 sdata[idxs++] = (i%width)/sigmaS;
3405 sdata[idxs++] = (i/width)/sigmaS;
3406 sdata[idxs++] = data[idxd++]/sigmaR;
3412 sdata[idxs++] = (i%width)/sigmaS;
3413 sdata[idxs++] = (i/width)/sigmaS;
3415 sdata[idxs++] = data[idxd++]/sigmaR;
3426 sMaxs[0] = width/sigmaS;
3427 sMaxs[1] = height/sigmaS;
3428 sMins = sMaxs[2] = sdata[2];
3436 else if (cval > sMaxs[2])
3442 int nBuck1, nBuck2, nBuck3;
3443 int cBuck1, cBuck2, cBuck3, cBuck;
3444 nBuck1 = (int) (sMaxs[0] + 3);
3445 nBuck2 = (int) (sMaxs[1] + 3);
3446 nBuck3 = (int) (sMaxs[2] - sMins + 3);
3447 buckets =
new int[nBuck1*nBuck2*nBuck3];
3448 for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
3455 cBuck1 = (int) sdata[idxs] + 1;
3456 cBuck2 = (int) sdata[idxs+1] + 1;
3457 cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
3458 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
3460 slist[i] = buckets[cBuck];
3467 for (cBuck1=-1; cBuck1<=1; cBuck1++)
3469 for (cBuck2=-1; cBuck2<=1; cBuck2++)
3471 for (cBuck3=-1; cBuck3<=1; cBuck3++)
3473 bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
3477 double wsuml, weight;
3478 double hiLTr = 80.0/sigmaR;
3483 memset(modeTable, 0, width*height);
3487 msSys.Prompt(
"done.\nApplying mean shift (Using Lattice) ... ");
3488 #ifdef SHOW_PROGRESS
3489 msSys.Prompt(
"\n 0%%");
3494 for(i = 0; i < L; i++)
3499 if (modeTable[i] == 1)
3509 for (j=0; j<lN; j++)
3510 yk[j] = sdata[idxs+j];
3516 for(j = 0; j < lN; j++)
3521 cBuck1 = (int) yk[0] + 1;
3522 cBuck2 = (int) yk[1] + 1;
3523 cBuck3 = (int) (yk[2] - sMins) + 1;
3524 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
3525 for (j=0; j<27; j++)
3527 idxd = buckets[cBuck+bucNeigh[j]];
3533 el = sdata[idxs+0]-yk[0];
3535 el = sdata[idxs+1]-yk[1];
3540 el = sdata[idxs+2]-yk[2];
3548 el = sdata[idxs+3]-yk[3];
3550 el = sdata[idxs+4]-yk[4];
3556 weight = 1-weightMap[idxd];
3557 for (k=0; k<lN; k++)
3558 Mh[k] += weight*sdata[idxs+k];
3567 for(j = 0; j < lN; j++)
3568 Mh[j] = Mh[j]/wsuml - yk[j];
3572 for(j = 0; j < lN; j++)
3580 mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
3582 mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
3584 mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
3594 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
3598 for(j = 0; j < lN; j++)
3605 modeCandidateX = (int) (sigmaS*yk[0]+0.5);
3606 modeCandidateY = (int) (sigmaS*yk[1]+0.5);
3607 modeCandidate_i = modeCandidateY*width + modeCandidateX;
3622 if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
3628 idxs = lN*modeCandidate_i;
3629 for (k=2; k<lN; k++)
3631 el = sdata[idxs+k] - yk[k];
3639 if (diff < TC_DIST_FACTOR)
3645 if (modeTable[modeCandidate_i] == 0)
3649 pointList[pointCount++] = modeCandidate_i;
3650 modeTable[modeCandidate_i] = 2;
3661 for (j = 0; j < N; j++)
3662 yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR;
3685 for(j = 0; j < lN; j++)
3690 cBuck1 = (int) yk[0] + 1;
3691 cBuck2 = (int) yk[1] + 1;
3692 cBuck3 = (int) (yk[2] - sMins) + 1;
3693 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
3694 for (j=0; j<27; j++)
3696 idxd = buckets[cBuck+bucNeigh[j]];
3702 el = sdata[idxs+0]-yk[0];
3704 el = sdata[idxs+1]-yk[1];
3709 el = sdata[idxs+2]-yk[2];
3717 el = sdata[idxs+3]-yk[3];
3719 el = sdata[idxs+4]-yk[4];
3725 weight = 1-weightMap[idxd];
3726 for (k=0; k<lN; k++)
3727 Mh[k] += weight*sdata[idxs+k];
3736 for(j = 0; j < lN; j++)
3737 Mh[j] = Mh[j]/wsuml - yk[j];
3741 for(j = 0; j < lN; j++)
3750 mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
3752 mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
3754 mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
3766 for(j = 0; j < lN; j++)
3782 for (j = 0; j < pointCount; j++)
3786 modeCandidate_i = pointList[j];
3789 modeTable[modeCandidate_i] = 1;
3792 for(k = 0; k < N; k++)
3793 msRawData[N*modeCandidate_i+k] = (
float)(yk[k+2]);
3797 for(j = 0; j < N; j++)
3798 msRawData[N*i+j] = (
float)(yk[j+2]);
3801 #ifdef SHOW_PROGRESS
3802 percent_complete = (float)(i/(
float)(L))*100;
3803 msSys.Prompt(
"\r%2d%%", (
int)(percent_complete + 0.5));
3807 if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((
float)(i/(float)(L))*(
float)(0.8)))) == EL_HALT)
3813 #ifdef SHOW_PROGRESS
3816 msSys.Prompt(
"done.");
3832 void msImageProcessor::NewOptimizedFilter2(
float sigmaS,
float sigmaR)
3835 int iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i;
3836 double mvAbs, diff, el;
3842 ErrorHandler(
"msImageProcessor",
"LFilter",
"Lattice height and width are undefined.");
3847 if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
3849 ErrorHandler(
"msImageProcessor",
"Segment",
"sigmaS and/or sigmaR is zero or negative.");
3860 double *yk =
new double [lN];
3863 double *Mh =
new double [lN];
3867 sdata =
new float[lN*L];
3876 sdata[idxs++] = (i%width)/sigmaS;
3877 sdata[idxs++] = (i/width)/sigmaS;
3878 sdata[idxs++] = data[idxd++]/sigmaR;
3879 sdata[idxs++] = data[idxd++]/sigmaR;
3880 sdata[idxs++] = data[idxd++]/sigmaR;
3886 sdata[idxs++] = (i%width)/sigmaS;
3887 sdata[idxs++] = (i/width)/sigmaS;
3888 sdata[idxs++] = data[idxd++]/sigmaR;
3894 sdata[idxs++] = (i%width)/sigmaS;
3895 sdata[idxs++] = (i/width)/sigmaS;
3897 sdata[idxs++] = data[idxd++]/sigmaR;
3908 sMaxs[0] = width/sigmaS;
3909 sMaxs[1] = height/sigmaS;
3910 sMins = sMaxs[2] = sdata[2];
3918 else if (cval > sMaxs[2])
3924 int nBuck1, nBuck2, nBuck3;
3925 int cBuck1, cBuck2, cBuck3, cBuck;
3926 nBuck1 = (int) (sMaxs[0] + 3);
3927 nBuck2 = (int) (sMaxs[1] + 3);
3928 nBuck3 = (int) (sMaxs[2] - sMins + 3);
3929 buckets =
new int[nBuck1*nBuck2*nBuck3];
3930 for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
3937 cBuck1 = (int) sdata[idxs] + 1;
3938 cBuck2 = (int) sdata[idxs+1] + 1;
3939 cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
3940 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
3942 slist[i] = buckets[cBuck];
3949 for (cBuck1=-1; cBuck1<=1; cBuck1++)
3951 for (cBuck2=-1; cBuck2<=1; cBuck2++)
3953 for (cBuck3=-1; cBuck3<=1; cBuck3++)
3955 bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
3959 double wsuml, weight;
3960 double hiLTr = 80.0/sigmaR;
3965 memset(modeTable, 0, width*height);
3969 msSys.Prompt(
"done.\nApplying mean shift (Using Lattice) ... ");
3970 #ifdef SHOW_PROGRESS
3971 msSys.Prompt(
"\n 0%%");
3976 for(i = 0; i < L; i++)
3981 if (modeTable[i] == 1)
3991 for (j=0; j<lN; j++)
3992 yk[j] = sdata[idxs+j];
3998 for(j = 0; j < lN; j++)
4003 cBuck1 = (int) yk[0] + 1;
4004 cBuck2 = (int) yk[1] + 1;
4005 cBuck3 = (int) (yk[2] - sMins) + 1;
4006 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
4007 for (j=0; j<27; j++)
4009 idxd = buckets[cBuck+bucNeigh[j]];
4015 el = sdata[idxs+0]-yk[0];
4017 el = sdata[idxs+1]-yk[1];
4022 el = sdata[idxs+2]-yk[2];
4030 el = sdata[idxs+3]-yk[3];
4032 el = sdata[idxs+4]-yk[4];
4038 weight = 1-weightMap[idxd];
4039 for (k=0; k<lN; k++)
4040 Mh[k] += weight*sdata[idxs+k];
4044 if (diff < speedThreshold)
4046 if(modeTable[idxd] == 0)
4048 pointList[pointCount++] = idxd;
4049 modeTable[idxd] = 2;
4059 for(j = 0; j < lN; j++)
4060 Mh[j] = Mh[j]/wsuml - yk[j];
4064 for(j = 0; j < lN; j++)
4072 mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
4074 mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
4076 mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
4086 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
4090 for(j = 0; j < lN; j++)
4097 modeCandidateX = (int) (sigmaS*yk[0]+0.5);
4098 modeCandidateY = (int) (sigmaS*yk[1]+0.5);
4099 modeCandidate_i = modeCandidateY*width + modeCandidateX;
4114 if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
4120 idxs = lN*modeCandidate_i;
4121 for (k=2; k<lN; k++)
4123 el = sdata[idxs+k] - yk[k];
4131 if (diff < speedThreshold)
4137 if (modeTable[modeCandidate_i] == 0)
4141 pointList[pointCount++] = modeCandidate_i;
4142 modeTable[modeCandidate_i] = 2;
4153 for (j = 0; j < N; j++)
4154 yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR;
4177 for(j = 0; j < lN; j++)
4182 cBuck1 = (int) yk[0] + 1;
4183 cBuck2 = (int) yk[1] + 1;
4184 cBuck3 = (int) (yk[2] - sMins) + 1;
4185 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
4186 for (j=0; j<27; j++)
4188 idxd = buckets[cBuck+bucNeigh[j]];
4194 el = sdata[idxs+0]-yk[0];
4196 el = sdata[idxs+1]-yk[1];
4201 el = sdata[idxs+2]-yk[2];
4209 el = sdata[idxs+3]-yk[3];
4211 el = sdata[idxs+4]-yk[4];
4217 weight = 1-weightMap[idxd];
4218 for (k=0; k<lN; k++)
4219 Mh[k] += weight*sdata[idxs+k];
4223 if (diff < speedThreshold)
4225 if(modeTable[idxd] == 0)
4227 pointList[pointCount++] = idxd;
4228 modeTable[idxd] = 2;
4239 for(j = 0; j < lN; j++)
4240 Mh[j] = Mh[j]/wsuml - yk[j];
4244 for(j = 0; j < lN; j++)
4253 mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
4255 mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
4257 mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
4269 for(j = 0; j < lN; j++)
4285 for (j = 0; j < pointCount; j++)
4289 modeCandidate_i = pointList[j];
4292 modeTable[modeCandidate_i] = 1;
4295 for(k = 0; k < N; k++)
4296 msRawData[N*modeCandidate_i+k] = (
float)(yk[k+2]);
4300 for(j = 0; j < N; j++)
4301 msRawData[N*i+j] = (
float)(yk[j+2]);
4304 #ifdef SHOW_PROGRESS
4305 percent_complete = (float)(i/(
float)(L))*100;
4306 msSys.Prompt(
"\r%2d%%", (
int)(percent_complete + 0.5));
4310 if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((
float)(i/(float)(L))*(
float)(0.8)))) == EL_HALT)
4316 #ifdef SHOW_PROGRESS
4319 msSys.Prompt(
"done.");
4334 void msImageProcessor::NewNonOptimizedFilter(
float sigmaS,
float sigmaR)
4338 int iterationCount, i, j, k;
4339 double mvAbs, diff, el;
4345 ErrorHandler(
"msImageProcessor",
"LFilter",
"Lattice height and width are undefined.");
4350 if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
4352 ErrorHandler(
"msImageProcessor",
"Segment",
"sigmaS and/or sigmaR is zero or negative.");
4363 double *yk =
new double [lN];
4366 double *Mh =
new double [lN];
4370 sdata =
new double[lN*L];
4379 sdata[idxs++] = (i%width)/sigmaS;
4380 sdata[idxs++] = (i/width)/sigmaS;
4381 sdata[idxs++] = data[idxd++]/sigmaR;
4382 sdata[idxs++] = data[idxd++]/sigmaR;
4383 sdata[idxs++] = data[idxd++]/sigmaR;
4389 sdata[idxs++] = (i%width)/sigmaS;
4390 sdata[idxs++] = (i/width)/sigmaS;
4391 sdata[idxs++] = data[idxd++]/sigmaR;
4397 sdata[idxs++] = (i%width)/sigmaS;
4398 sdata[idxs++] = (i%width)/sigmaS;
4400 sdata[idxs++] = data[idxd++]/sigmaR;
4411 sMaxs[0] = width/sigmaS;
4412 sMaxs[1] = height/sigmaS;
4413 sMins = sMaxs[2] = sdata[2];
4421 else if (cval > sMaxs[2])
4427 int nBuck1, nBuck2, nBuck3;
4428 int cBuck1, cBuck2, cBuck3, cBuck;
4429 nBuck1 = (int) (sMaxs[0] + 3);
4430 nBuck2 = (int) (sMaxs[1] + 3);
4431 nBuck3 = (int) (sMaxs[2] - sMins + 3);
4432 buckets =
new int[nBuck1*nBuck2*nBuck3];
4433 for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
4440 cBuck1 = (int) sdata[idxs] + 1;
4441 cBuck2 = (int) sdata[idxs+1] + 1;
4442 cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
4443 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
4445 slist[i] = buckets[cBuck];
4452 for (cBuck1=-1; cBuck1<=1; cBuck1++)
4454 for (cBuck2=-1; cBuck2<=1; cBuck2++)
4456 for (cBuck3=-1; cBuck3<=1; cBuck3++)
4458 bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
4462 double wsuml, weight;
4463 double hiLTr = 80.0/sigmaR;
4468 msSys.Prompt(
"done.\nApplying mean shift (Using Lattice)... ");
4469 #ifdef SHOW_PROGRESS
4470 msSys.Prompt(
"\n 0%%");
4474 for(i = 0; i < L; i++)
4481 for (j=0; j<lN; j++)
4482 yk[j] = sdata[idxs+j];
4488 for(j = 0; j < lN; j++)
4493 cBuck1 = (int) yk[0] + 1;
4494 cBuck2 = (int) yk[1] + 1;
4495 cBuck3 = (int) (yk[2] - sMins) + 1;
4496 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
4497 for (j=0; j<27; j++)
4499 idxd = buckets[cBuck+bucNeigh[j]];
4505 el = sdata[idxs+0]-yk[0];
4507 el = sdata[idxs+1]-yk[1];
4512 el = sdata[idxs+2]-yk[2];
4520 el = sdata[idxs+3]-yk[3];
4522 el = sdata[idxs+4]-yk[4];
4528 weight = 1-weightMap[idxd];
4529 for (k=0; k<lN; k++)
4530 Mh[k] += weight*sdata[idxs+k];
4539 for(j = 0; j < lN; j++)
4540 Mh[j] = Mh[j]/wsuml - yk[j];
4544 for(j = 0; j < lN; j++)
4551 for(j = 0; j < lN; j++)
4552 mvAbs += Mh[j]*Mh[j];
4561 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
4565 for(j = 0; j < lN; j++)
4573 for(j = 0; j < lN; j++)
4578 cBuck1 = (int) yk[0] + 1;
4579 cBuck2 = (int) yk[1] + 1;
4580 cBuck3 = (int) (yk[2] - sMins) + 1;
4581 cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
4582 for (j=0; j<27; j++)
4584 idxd = buckets[cBuck+bucNeigh[j]];
4590 el = sdata[idxs+0]-yk[0];
4592 el = sdata[idxs+1]-yk[1];
4597 el = sdata[idxs+2]-yk[2];
4605 el = sdata[idxs+3]-yk[3];
4607 el = sdata[idxs+4]-yk[4];
4613 weight = 1-weightMap[idxd];
4614 for (k=0; k<lN; k++)
4615 Mh[k] += weight*sdata[idxs+k];
4624 for(j = 0; j < lN; j++)
4625 Mh[j] = Mh[j]/wsuml - yk[j];
4629 for(j = 0; j < lN; j++)
4638 mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
4640 mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
4642 mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
4649 for(j = 0; j < lN; j++)
4653 for(j = 0; j < N; j++)
4654 msRawData[N*i+j] = (
float)(yk[j+2]*sigmaR);
4657 #ifdef SHOW_PROGRESS
4658 percent_complete = (float)(i/(
float)(L))*100;
4659 msSys.Prompt(
"\r%2d%%", (
int)(percent_complete + 0.5));
4663 if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((
float)(i/(float)(L))*(
float)(0.8)))) == EL_HALT)
4669 #ifdef SHOW_PROGRESS
4672 msSys.Prompt(
"done.");
4688 void msImageProcessor::SetSpeedThreshold(
float speedUpThreshold)
4690 speedThreshold = speedUpThreshold;