72 MeanShift::MeanShift(
void )
99 uniformKernel =
false;
111 weightMapDefined =
false;
114 ErrorMessage =
new char [256];
117 ErrorStatus = EL_OKAY;
120 class_state.INPUT_DEFINED =
false;
121 class_state.KERNEL_DEFINED =
false;
122 class_state.LATTICE_DEFINED =
false;
123 class_state.OUTPUT_DEFINED =
false;
135 MeanShift::~MeanShift(
void )
137 delete [] ErrorMessage;
145 ClearWeightFunctions();
181 void MeanShift::DefineKernel(kernelType *kernel_,
float *h_,
int *P_,
int kp_)
194 ErrorHandler(
"MeanShift",
"CreateKernel",
"Subspace count (kp) is zero or negative.");
199 if((!(P =
new int [kp]))||(!(h =
new float [kp]))||(!(kernel =
new kernelType [kp]))||
200 (!(offset =
new float [kp]))||(!(increment =
new double [kp])))
202 ErrorHandler(
"MeanShift",
"CreateKernel",
"Not enough memory available to create kernel.");
209 for(i = 0; i < kp; i++)
211 if((h[i] = h_[i]) <= 0)
213 ErrorHandler(
"MeanShift",
"CreateKernel",
"Negative or zero valued bandwidths are prohibited.");
216 if((P[i] = P_[i]) <= 0)
218 ErrorHandler(
"MeanShift",
"CreateKernel",
"Negative or zero valued subspace dimensions are prohibited.");
221 kernel[i] = kernel_[i];
226 if((!(range =
new float [2*kN]))||(!(uv =
new double [kN])))
228 ErrorHandler(
"MeanShift",
"CreateKernel",
"Not enough memory available to create kernel.");
235 generateLookupTable();
238 if(ErrorStatus == EL_ERROR)
242 class_state.KERNEL_DEFINED =
true;
274 void MeanShift::AddWeightFunction(
double g(
double),
float halfWindow,
int sampleNumber,
int subspace)
288 while((cur)&&(cur->subspace != subspace))
297 cur =
new userWeightFunct;
303 increment = halfWindow/(double)(sampleNumber);
305 cur->w =
new double [sampleNumber+1];
306 for(i = 0; i <= sampleNumber; i++)
307 cur->w[i] = g((
double)(i*increment));
310 cur->halfWindow = halfWindow;
311 cur->sampleNumber = sampleNumber;
312 cur->subspace = subspace;
331 void MeanShift::ClearWeightFunctions(
void )
363 void MeanShift::DefineInput(
float *x,
int L_,
int N_)
369 if((class_state.INPUT_DEFINED)||(class_state.LATTICE_DEFINED))
375 ErrorHandler(
"MeanShift",
"UploadInput",
"Input data set is NULL.");
380 if(((L = L_) <= 0)||((N = N_) <= 0))
382 ErrorHandler(
"MeanShift",
"UploadInput",
"Input data set has negative or zero length or dimension.");
387 if(!(data =
new float [L*N]))
389 ErrorHandler(
"MeanShift",
"UploadInput",
"Not enough memory.");
399 if(ErrorStatus == EL_ERROR)
410 class_state.INPUT_DEFINED =
true;
411 class_state.LATTICE_DEFINED =
false;
412 class_state.OUTPUT_DEFINED =
false;
436 void MeanShift::DefineLInput(
float *x,
int ht,
int wt,
int N_)
441 if((class_state.INPUT_DEFINED)||(class_state.LATTICE_DEFINED))
445 if(((height = ht) <= 0)||((width = wt) <= 0))
447 ErrorHandler(
"MeanShift",
"DefineLInput",
"Lattice defined using zero or negative height and/or width.");
454 ErrorHandler(
"MeanShift",
"DefineInput",
"Input defined using zero or negative dimension.");
468 if(ErrorStatus == EL_ERROR)
472 if(!(weightMap =
new float [L]))
474 ErrorHandler(
"MeanShift",
"InitializeInput",
"Not enough memory.");
479 memset(weightMap, 0, L*(
sizeof(
float)));
483 class_state.LATTICE_DEFINED =
true;
484 class_state.INPUT_DEFINED =
false;
485 class_state.OUTPUT_DEFINED =
false;
507 void MeanShift::SetLatticeWeightMap(
float *wm)
512 ErrorHandler(
"MeanShift",
"SetWeightMap",
"Specified weight map is NULL.");
518 for(i = 0; i < L; i++)
519 weightMap[i] = wm[i];
522 weightMapDefined =
true;
541 void MeanShift::RemoveLatticeWeightMap(
void)
549 memset(weightMap, 0, L*
sizeof(
float));
553 weightMapDefined =
false;
582 void MeanShift::msVector(
double *Mh,
double *yk)
588 ErrorHandler(
"MeanShift",
"msVector",
"Invalid argument(s) passed to this method.");
595 classConsistencyCheck(N,
false);
627 void MeanShift::latticeMSVector(
double *Mh,
double *yk)
633 ErrorHandler(
"MeanShift",
"lmsVector",
"Invalid argument(s) passed to this method.");
640 classConsistencyCheck(N+2,
true);
644 LatticeMSVector(Mh, yk);
666 void MeanShift::FindMode(
double *mode,
double *yk)
672 ErrorHandler(
"MeanShift",
"FindMode",
"Invalid argument(s) passed to this method.");
679 classConsistencyCheck(N,
false);
682 double *Mh =
new double [N];
686 for(i = 0; i < N; i++)
694 for(i = 0; i < N; i++)
695 mvAbs += Mh[i]*Mh[i];
698 int iterationCount = 1;
699 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
702 for(i = 0; i < N; i++)
712 for(i = 0; i < N; i++)
713 mvAbs += Mh[i]*Mh[i];
721 for(i = 0; i < N; i++)
753 void MeanShift::FindLMode(
double *mode,
double *yk)
759 ErrorHandler(
"MeanShift",
"FindLMode",
"Invalid argument(s) passed to this method.");
766 ErrorHandler(
"MeanShift",
"FindLMode",
"Lattice height and width is undefined.");
773 classConsistencyCheck(N+2,
true);
779 double *Mh =
new double [gridN];
783 for(i = 0; i < gridN; i++)
787 LatticeMSVector(Mh, mode);
791 for(i = 0; i < gridN; i++)
792 mvAbs += Mh[i]*Mh[i];
795 int iterationCount = 1;
796 while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
799 for(i = 0; i < gridN; i++)
805 LatticeMSVector(Mh, mode);
809 for(i = 0; i < gridN; i++)
810 mvAbs += Mh[i]*Mh[i];
818 for(i = 0; i < gridN; i++)
859 void MeanShift::MSVector(
double *Mh_ptr,
double *yk_ptr)
866 for(i = 0; i < N; i++)
882 for(i = 0; i < kp; i++)
884 for(j = 0; j < P[i]; j++)
886 range[2*(s+j) ] = (
float)(yk_ptr[s+j] - h[i]);
887 range[2*(s+j)+1] = (
float)(yk_ptr[s+j] + h[i]);
894 for(i = 0; i < kp; i++)
896 for(j = 0; j < P[i]; j++)
898 range[2*(s+j) ] = (
float)(yk_ptr[s+j] - h[i]*float(sqrt(offset[i])));
899 range[2*(s+j)+1] = (
float)(yk_ptr[s+j] + h[i]*float(sqrt(offset[i])));
911 uniformSearch(root, 0, Mh_ptr, yk_ptr);
913 generalSearch(root, 0, Mh_ptr, yk_ptr);
916 for(i = 0; i < N; i++)
923 Mh_ptr[i] -= yk_ptr[i];
954 void MeanShift::LatticeMSVector(
double *Mh_ptr,
double *yk_ptr)
959 for(i = 0; i < N+2; i++)
970 uniformLSearch(Mh_ptr, yk_ptr);
972 generalLSearch(Mh_ptr, yk_ptr);
980 for(i = 0; i < N+2; i++)
981 Mh_ptr[i] = Mh_ptr[i]/wsum - yk_ptr[i];
985 for(i = 0; i < N+2; i++)
1018 void MeanShift::OptLatticeMSVector(
double *Mh_ptr,
double *yk_ptr)
1023 for(i = 0; i < N+2; i++)
1034 optUniformLSearch(Mh_ptr, yk_ptr);
1036 optGeneralLSearch(Mh_ptr, yk_ptr);
1044 for(i = 0; i < N+2; i++)
1045 Mh_ptr[i] = Mh_ptr[i]/wsum - yk_ptr[i];
1048 for (i=0; i< N+2; i++)
1078 void MeanShift::classConsistencyCheck(
int iN,
bool usingLattice)
1082 if(class_state.KERNEL_DEFINED ==
false)
1084 ErrorHandler(
"MeanShift",
"classConsistencyCheck",
"Kernel not created.");
1089 if((class_state.INPUT_DEFINED ==
false)&&(!usingLattice))
1091 ErrorHandler(
"MeanShift",
"classConsistencyCheck",
"No input data specified.");
1096 if((class_state.LATTICE_DEFINED ==
false)&&(usingLattice))
1098 ErrorHandler(
"MeanShift",
"classConsistencyCheck",
"Latice not created.");
1107 for(i = 0; i < kp; i++)
1113 ErrorHandler(
"MeanShift",
"classConsitencyCheck",
"Kernel dimension does not match defined input data dimension.");
1150 void MeanShift::ErrorHandler(
const char *className,
const char *methodName,
const char* errmsg)
1154 strcpy(ErrorMessage, className);
1155 strcat(ErrorMessage,
"::");
1156 strcat(ErrorMessage, methodName);
1157 strcat(ErrorMessage,
" Error: ");
1160 strcat(ErrorMessage, errmsg);
1163 ErrorStatus = EL_ERROR;
1203 void MeanShift::generateLookupTable(
void )
1210 w =
new double*[kp];
1216 uniformKernel =
true;
1218 for(i = 0; i < kp; i++)
1237 uniformKernel =
false;
1243 w[i] =
new double [GAUSS_NUM_ELS+1];
1245 for(j = 0; j <= GAUSS_NUM_ELS; j++)
1246 w[i][j] = exp(-j*GAUSS_INCREMENT/2);
1249 offset [i] = (float)(GAUSS_LIMIT*GAUSS_LIMIT);
1250 increment[i] = GAUSS_INCREMENT;
1259 uniformKernel =
false;
1264 while((cur)&&(cur->subspace != (i+1)))
1271 fprintf(stderr,
"\ngenerateLookupTable Fatal Error: User defined kernel for subspace %d undefined.\n\nAborting Program.\n\n", i+1);
1276 w[i] =
new double [cur->sampleNumber+1];
1277 for(j = 0; j <= cur->sampleNumber; j++)
1278 w[i][j] = cur->w[j];
1281 offset [i] = (
float)(cur->halfWindow);
1282 increment[i] = cur->halfWindow/(float)(cur->sampleNumber);
1289 ErrorHandler(
"MeanShift",
"generateLookupTable",
"Unknown kernel type.");
1307 void MeanShift::DestroyKernel(
void )
1311 if(kernel)
delete [] kernel;
1314 if (range)
delete [] range;
1316 if (uv)
delete [] uv;
1317 if(increment)
delete [] increment;
1318 if (offset)
delete [] offset;
1325 for (i=0; i<kp; i++)
1366 void MeanShift::CreateBST(
void )
1372 forest =
new tree[L];
1377 for(i = 0; i < L; i++)
1379 forest[i].x = &data[i*N];
1380 forest[i].right = NULL;
1381 forest[i].left = NULL;
1382 forest[i].parent = NULL;
1389 root = BuildKDTree(forest, L, 0, NULL);
1412 void MeanShift::InitializeInput(
float *x)
1416 if(!(data =
new float [L*N]))
1418 ErrorHandler(
"MeanShift",
"InitializeInput",
"Not enough memory.");
1424 for(i = 0; i < L*N; i++)
1444 void MeanShift::ResetInput(
void )
1448 if(data)
delete [] data;
1449 if(forest)
delete [] forest;
1463 class_state.INPUT_DEFINED = class_state.LATTICE_DEFINED =
false;
1489 tree *MeanShift::BuildKDTree(tree *subset,
int length,
int d, tree* parent)
1501 subset->parent = parent;
1508 QuickMedian(subset, 0, length-1, d);
1515 int median = length/2;
1516 subset[median].parent = parent;
1517 subset[median].left = BuildKDTree(subset , median , (d+1)%N, &subset[median]);
1518 subset[median].right = BuildKDTree(&subset[median+1], length-median-1, (d+1)%N, &subset[median]);
1521 return &subset[median];
1556 void MeanShift::QuickMedian(tree *arr,
int left,
int right,
int d)
1564 unsigned long i, ir, j, l, mid;
1572 if (ir == l+1 && arr[ir-1].x[d] < arr[l-1].x[d])
1574 SWAP(arr[l-1].x, arr[ir-1].x)
1580 SWAP(arr[mid-1].x, arr[l+1-1].x)
1581 if (arr[l-1].x[d] > arr[ir-1].x[d])
1583 SWAP(arr[l-1].x, arr[ir-1].x)
1585 if (arr[l+1-1].x[d] > arr[ir-1].x[d])
1587 SWAP(arr[l+1-1].x, arr[ir-1].x)
1589 if (arr[l-1].x[d] > arr[l+1-1].x[d])
1591 SWAP(arr[l-1].x, arr[l+1-1].x)
1597 do i++;
while (arr[i-1].x[d] < a[d]);
1598 do j--;
while (arr[j-1].x[d] > a[d]);
1600 SWAP(arr[i-1].x, arr[j-1].x)
1602 arr[l+1-1].x = arr[j-1].x;
1634 void MeanShift::uniformSearch(tree *gt,
int gd,
double *Mh_ptr,
double *yk_ptr)
1650 switch(actionType) {
1652 if ((c_t->x[c_d] > range[2*c_d]) && ((c_t->left) != NULL))
1663 for(i = 0; i < N; i++)
1665 if((c_t->x[i] < range[2*i])||(c_t->x[i] > range[2*i+1]))
1679 while((diff < 1.0)&&(j < kp))
1684 for(k = 0; k < P[j]; k++)
1686 el = (c_t->x[s+k] - yk_ptr[s+k])/h[j];
1698 for(j = 0; j < N; j++)
1699 Mh_ptr[j] += c_t->x[j];
1703 if ((c_t->x[c_d] < range[2*c_d+1]) && ((c_t->right) != NULL))
1716 if (c_t->parent == NULL)
1722 if (c_t->parent->left == c_t)
1752 void MeanShift::generalSearch(tree *gt,
int gd,
double *Mh_ptr,
double *yk_ptr)
1763 double el, diff, u, tw, y0, y1;
1764 int k, j, s, x0, x1;
1768 switch(actionType) {
1770 if ((c_t->x[c_d] > range[2*c_d]) && ((c_t->left) != NULL))
1781 for(i = 0; i < N; i++)
1783 if((c_t->x[i] < range[2*i])||(c_t->x[i] > range[2*i+1]))
1795 for(j = 0; j < kp; j++)
1800 for(k = 0; k < P[j]; k++)
1802 el = (c_t->x[s+k] - yk_ptr[s+k])/h[j];
1803 diff += uv[s+k] = el*el;
1804 if(diff >= offset[j])
1808 if(diff >= offset[j])
1818 if(diff < offset[j])
1827 for(j = 0; j < kp; j++)
1833 for(k = 0; k < P[j]; k++)
1844 x0 = (int)(u/increment[j]);
1852 tw *= (((double)(x1)*increment[j] - u)*y0+(u - (
double)(x0)*increment[j])*y1)/(
double)(x1*increment[j] - x0*increment[j]);
1859 for(j = 0; j < N; j++)
1860 Mh_ptr[j] += tw*c_t->x[j];
1867 if ((c_t->x[c_d] < range[2*c_d+1]) && ((c_t->right) != NULL))
1880 if (c_t->parent == NULL)
1886 if (c_t->parent->left == c_t)
1926 void MeanShift::uniformLSearch(
double *Mh_ptr,
double *yk_ptr)
1930 register int i, j, k;
1931 int s, p, dataPoint, lN;
1932 double diff, el, dx, dy, tx, weight;
1942 tx = yk_ptr[0] - h[0] + DELTA + 0.99;
1946 LowerBoundX = (int) tx;
1947 tx = yk_ptr[1] - h[0] + DELTA + 0.99;
1951 LowerBoundY = (int) tx;
1952 tx = yk_ptr[0] + h[0] - DELTA;
1954 UpperBoundX = width-1;
1956 UpperBoundX = (int) tx;
1957 tx = yk_ptr[1] + h[0] - DELTA;
1959 UpperBoundY = height - 1;
1961 UpperBoundY = (int) tx;
1964 for(i = LowerBoundY; i <= UpperBoundY; i++)
1965 for(j = LowerBoundX; j <= UpperBoundX; j++)
1969 dataPoint = N*(i*width+j);
1976 diff = (dx*dx+dy*dy)/(h[0]*h[0]);
1977 while((diff < 1.0)&&(k != kp))
1981 for(p = 0; p < P[k]; p++)
1983 el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k];
1984 if((!p)&&(yk_ptr[2] > 80))
1998 weight = 1 - weightMap[i*width+j];
1999 Mh_ptr[0] += weight*j;
2000 Mh_ptr[1] += weight*i;
2001 for(k = 2; k < lN; k++)
2002 Mh_ptr[k] += weight*data[dataPoint+k-2];
2043 void MeanShift::optUniformLSearch(
double *Mh_ptr,
double *yk_ptr)
2047 register int i, j, k;
2048 int s, p, dataPoint, pointIndx, lN;
2049 double diff, el, dx, dy, tx, weight;
2059 tx = yk_ptr[0] - h[0] + DELTA + 0.99;
2063 LowerBoundX = (int) tx;
2064 tx = yk_ptr[1] - h[0] + DELTA + 0.99;
2068 LowerBoundY = (int) tx;
2069 tx = yk_ptr[0] + h[0] - DELTA;
2071 UpperBoundX = width-1;
2073 UpperBoundX = (int) tx;
2074 tx = yk_ptr[1] + h[0] - DELTA;
2076 UpperBoundY = height - 1;
2078 UpperBoundY = (int) tx;
2081 for(i = LowerBoundY; i <= UpperBoundY; i++)
2082 for(j = LowerBoundX; j <= UpperBoundX; j++)
2086 pointIndx = i*width+j;
2087 dataPoint = N*(pointIndx);
2094 diff = (dx*dx+dy*dy)/(h[0]*h[0]);
2095 while((diff < 1.0)&&(k != kp))
2099 for(p = 0; p < P[k]; p++)
2101 el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k];
2102 if((!p)&&(yk_ptr[2] > 80))
2116 weight = 1 - weightMap[i*width+j];
2117 Mh_ptr[0] += weight*j;
2118 Mh_ptr[1] += weight*i;
2119 for(k = 2; k < lN; k++)
2120 Mh_ptr[k] += weight*data[dataPoint+k-2];
2126 if(modeTable[pointIndx] == 0)
2128 pointList[pointCount++] = pointIndx;
2129 modeTable[pointIndx] = 2;
2166 void MeanShift::generalLSearch(
double *Mh_ptr,
double *yk_ptr)
2170 register int i, j, k;
2171 int s, p, dataPoint, lN, x0, x1;
2172 double diff, el, dx, dy, tw, u, y0, y1, tx;
2182 tx = yk_ptr[0] - h[0] + DELTA + 0.99;
2186 LowerBoundX = (int) tx;
2187 tx = yk_ptr[1] - h[0] + DELTA + 0.99;
2191 LowerBoundY = (int) tx;
2192 tx = yk_ptr[0] + h[0] - DELTA;
2194 UpperBoundX = width-1;
2196 UpperBoundX = (int) tx;
2197 tx = yk_ptr[1] + h[0] - DELTA;
2199 UpperBoundY = height - 1;
2201 UpperBoundY = (int) tx;
2204 for(i = LowerBoundY; i <= UpperBoundY; i++)
2205 for(j = LowerBoundX; j <= UpperBoundX; j++)
2209 dataPoint = N*(i*width+j);
2216 uv[0] = (dx*dx)/(h[0]*h[0]);
2217 uv[1] = (dy*dy)/(h[0]*h[0]);
2218 diff = uv[0] + uv[1];
2219 while((diff < offset[k-1])&&(k != kp))
2223 for(p = 0; p < P[k]; p++)
2225 el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k];
2226 diff += uv[p+s+2] = el*el;
2235 if(diff < offset[k-1])
2244 for(k = 0; k < kp; k++)
2250 for(p = 0; p < P[k]; p++)
2261 x0 = (int)(u/increment[k]);
2269 tw *= (((double)(x1)*increment[k] - u)*y0+(u - (
double)(x0)*increment[k])*y1)/(
double)(x1*increment[k] - x0*increment[k]);
2278 for(k = 0; k < N; k++)
2279 Mh_ptr[k+2] += tw*data[dataPoint+k];
2322 void MeanShift::optGeneralLSearch(
double *Mh_ptr,
double *yk_ptr)
2326 register int i, j, k;
2327 int s, p, dataPoint, pointIndx, lN, x0, x1;
2328 double diff, el, dx, dy, tw, u, y0, y1, tx;
2338 tx = yk_ptr[0] - h[0] + DELTA + 0.99;
2342 LowerBoundX = (int) tx;
2343 tx = yk_ptr[1] - h[0] + DELTA + 0.99;
2347 LowerBoundY = (int) tx;
2348 tx = yk_ptr[0] + h[0] - DELTA;
2350 UpperBoundX = width-1;
2352 UpperBoundX = (int) tx;
2353 tx = yk_ptr[1] + h[0] - DELTA;
2355 UpperBoundY = height - 1;
2357 UpperBoundY = (int) tx;
2360 for(i = LowerBoundY; i <= UpperBoundY; i++)
2361 for(j = LowerBoundX; j <= UpperBoundX; j++)
2365 pointIndx = i*width+j;
2366 dataPoint = N*(i*width+j);
2373 uv[0] = (dx*dx)/(h[0]*h[0]);
2374 uv[1] = (dy*dy)/(h[0]*h[0]);
2375 diff = uv[0] + uv[1];
2376 while((diff < offset[k-1])&&(k != kp))
2380 for(p = 0; p < P[k]; p++)
2382 el = (data[dataPoint+p+s]-yk_ptr[p+s+2])/h[k];
2383 diff += uv[p+s+2] = el*el;
2392 if(diff < offset[k-1])
2401 for(k = 0; k < kp; k++)
2407 for(p = 0; p < P[k]; p++)
2418 x0 = (int)(u/increment[k]);
2426 tw *= (((double)(x1)*increment[k] - u)*y0+(u - (
double)(x0)*increment[k])*y1)/(
double)(x1*increment[k] - x0*increment[k]);
2435 for(k = 0; k < N; k++)
2436 Mh_ptr[k+2] += tw*data[dataPoint+k];
2442 if(modeTable[pointIndx] == 0)
2444 pointList[pointCount++] = pointIndx;
2445 modeTable[pointIndx] = 2;