Esempio n. 1
0
File: mlem.cpp Progetto: glo/ee384b
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( &centers );
    cvReleaseMat( &old_centers );
    cvReleaseMat( &counters );
}
Esempio n. 2
0
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);
}