void CvEM::kmeans( const CvVectors& train_data, int nclusters, CvMat* labels, CvTermCriteria termcrit, const CvMat* centers0 ) { CvMat* centers = 0; CvMat* old_centers = 0; CvMat* counters = 0; CV_FUNCNAME( "CvEM::kmeans" ); __BEGIN__; CvRNG rng = cvRNG(-1); int i, j, k, nsamples, dims; int iter = 0; double max_dist = DBL_MAX; termcrit = cvCheckTermCriteria( termcrit, 1e-6, 100 ); termcrit.epsilon *= termcrit.epsilon; nsamples = train_data.count; dims = train_data.dims; nclusters = MIN( nclusters, nsamples ); CV_CALL( centers = cvCreateMat( nclusters, dims, CV_64FC1 )); CV_CALL( old_centers = cvCreateMat( nclusters, dims, CV_64FC1 )); CV_CALL( counters = cvCreateMat( 1, nclusters, CV_32SC1 )); cvZero( old_centers ); if( centers0 ) { CV_CALL( cvConvert( centers0, centers )); } else { for( i = 0; i < nsamples; i++ ) labels->data.i[i] = i*nclusters/nsamples; cvRandShuffle( labels, &rng ); } for( ;; ) { CvMat* temp; if( iter > 0 || centers0 ) { for( i = 0; i < nsamples; i++ ) { const float* s = train_data.data.fl[i]; int k_best = 0; double min_dist = DBL_MAX; for( k = 0; k < nclusters; k++ ) { const double* c = (double*)(centers->data.ptr + k*centers->step); double dist = 0; for( j = 0; j <= dims - 4; j += 4 ) { double t0 = c[j] - s[j]; double t1 = c[j+1] - s[j+1]; dist += t0*t0 + t1*t1; t0 = c[j+2] - s[j+2]; t1 = c[j+3] - s[j+3]; dist += t0*t0 + t1*t1; } for( ; j < dims; j++ ) { double t = c[j] - s[j]; dist += t*t; } if( min_dist > dist ) { min_dist = dist; k_best = k; } } labels->data.i[i] = k_best; } } if( ++iter > termcrit.max_iter ) break; CV_SWAP( centers, old_centers, temp ); cvZero( centers ); cvZero( counters ); // update centers for( i = 0; i < nsamples; i++ ) { const float* s = train_data.data.fl[i]; k = labels->data.i[i]; double* c = (double*)(centers->data.ptr + k*centers->step); for( j = 0; j <= dims - 4; j += 4 ) { double t0 = c[j] + s[j]; double t1 = c[j+1] + s[j+1]; c[j] = t0; c[j+1] = t1; t0 = c[j+2] + s[j+2]; t1 = c[j+3] + s[j+3]; c[j+2] = t0; c[j+3] = t1; } for( ; j < dims; j++ ) c[j] += s[j]; counters->data.i[k]++; } if( iter > 1 ) max_dist = 0; for( k = 0; k < nclusters; k++ ) { double* c = (double*)(centers->data.ptr + k*centers->step); if( counters->data.i[k] != 0 ) { double scale = 1./counters->data.i[k]; for( j = 0; j < dims; j++ ) c[j] *= scale; } else { const float* s; for( j = 0; j < 10; j++ ) { i = cvRandInt( &rng ) % nsamples; if( counters->data.i[labels->data.i[i]] > 1 ) break; } s = train_data.data.fl[i]; for( j = 0; j < dims; j++ ) c[j] = s[j]; } if( iter > 1 ) { double dist = 0; const double* c_o = (double*)(old_centers->data.ptr + k*old_centers->step); for( j = 0; j < dims; j++ ) { double t = c[j] - c_o[j]; dist += t*t; } if( max_dist < dist ) max_dist = dist; } } if( max_dist < termcrit.epsilon ) break; } cvZero( counters ); for( i = 0; i < nsamples; i++ ) counters->data.i[labels->data.i[i]]++; // ensure that we do not have empty clusters for( k = 0; k < nclusters; k++ ) if( counters->data.i[k] == 0 ) for(;;) { i = cvRandInt(&rng) % nsamples; j = labels->data.i[i]; if( counters->data.i[j] > 1 ) { labels->data.i[i] = k; counters->data.i[j]--; counters->data.i[k]++; break; } } __END__; cvReleaseMat( ¢ers ); cvReleaseMat( &old_centers ); cvReleaseMat( &counters ); }
CV_IMPL void cvFindStereoCorrespondenceGC(const CvArr* _left, const CvArr* _right, CvArr* _dispLeft, CvArr* _dispRight, CvStereoGCState* state, int useDisparityGuess) { CvStereoGCState2 state2; state2.orphans = 0; state2.maxOrphans = 0; CvMat lstub, *left = cvGetMat(_left, &lstub); CvMat rstub, *right = cvGetMat(_right, &rstub); CvMat dlstub, *dispLeft = cvGetMat(_dispLeft, &dlstub); CvMat drstub, *dispRight = cvGetMat(_dispRight, &drstub); CvSize size; int iter, i, nZeroExpansions = 0; CvRNG rng = cvRNG(-1); int* disp; CvMat _disp; int64 E; CV_Assert(state != 0); CV_Assert(CV_ARE_SIZES_EQ(left, right) && CV_ARE_TYPES_EQ(left, right) && CV_MAT_TYPE(left->type) == CV_8UC1); CV_Assert(!dispLeft || (CV_ARE_SIZES_EQ(dispLeft, left) && CV_MAT_CN(dispLeft->type) == 1)); CV_Assert(!dispRight || (CV_ARE_SIZES_EQ(dispRight, left) && CV_MAT_CN(dispRight->type) == 1)); size = cvGetSize(left); if (!state->left || state->left->width != size.width || state->left->height != size.height) { int pcn = (int)(sizeof(GCVtx*) / sizeof(int)); int vcn = (int)(sizeof(GCVtx) / sizeof(int)); int ecn = (int)(sizeof(GCEdge) / sizeof(int)); cvReleaseMat(&state->left); cvReleaseMat(&state->right); cvReleaseMat(&state->ptrLeft); cvReleaseMat(&state->ptrRight); cvReleaseMat(&state->dispLeft); cvReleaseMat(&state->dispRight); state->left = cvCreateMat(size.height, size.width, CV_8UC3); state->right = cvCreateMat(size.height, size.width, CV_8UC3); state->dispLeft = cvCreateMat(size.height, size.width, CV_16SC1); state->dispRight = cvCreateMat(size.height, size.width, CV_16SC1); state->ptrLeft = cvCreateMat(size.height, size.width, CV_32SC(pcn)); state->ptrRight = cvCreateMat(size.height, size.width, CV_32SC(pcn)); state->vtxBuf = cvCreateMat(1, size.height * size.width * 2, CV_32SC(vcn)); state->edgeBuf = cvCreateMat(1, size.height * size.width * 12 + 16, CV_32SC(ecn)); } if (!useDisparityGuess) { cvSet(state->dispLeft, cvScalarAll(OCCLUDED)); cvSet(state->dispRight, cvScalarAll(OCCLUDED)); } else { CV_Assert(dispLeft && dispRight); cvConvert(dispLeft, state->dispLeft); cvConvert(dispRight, state->dispRight); } state2.Ithreshold = state->Ithreshold; state2.interactionRadius = state->interactionRadius; state2.lambda = cvRound(state->lambda * DENOMINATOR); state2.lambda1 = cvRound(state->lambda1 * DENOMINATOR); state2.lambda2 = cvRound(state->lambda2 * DENOMINATOR); state2.K = cvRound(state->K * DENOMINATOR); icvInitStereoConstTabs(); icvInitGraySubpix(left, right, state->left, state->right); disp = (int*)cvStackAlloc(state->numberOfDisparities * sizeof(disp[0])); _disp = cvMat(1, state->numberOfDisparities, CV_32S, disp); cvRange(&_disp, state->minDisparity, state->minDisparity + state->numberOfDisparities); cvRandShuffle(&_disp, &rng); if (state2.lambda < 0 && (state2.K < 0 || state2.lambda1 < 0 || state2.lambda2 < 0)) { float L = icvComputeK(state) * 0.2f; state2.lambda = cvRound(L * DENOMINATOR); } if (state2.K < 0) { state2.K = state2.lambda * 5; } if (state2.lambda1 < 0) { state2.lambda1 = state2.lambda * 3; } if (state2.lambda2 < 0) { state2.lambda2 = state2.lambda; } icvInitStereoTabs(&state2); E = icvComputeEnergy(state, &state2, !useDisparityGuess); for (iter = 0; iter < state->maxIters; iter++) { for (i = 0; i < state->numberOfDisparities; i++) { int alpha = disp[i]; int64 Enew = icvAlphaExpand(E, -alpha, state, &state2); if (Enew < E) { nZeroExpansions = 0; E = Enew; } else if (++nZeroExpansions >= state->numberOfDisparities) { break; } } } if (dispLeft) { cvConvert(state->dispLeft, dispLeft); } if (dispRight) { cvConvert(state->dispRight, dispRight); } cvFree(&state2.orphans); }