コード例 #1
0
//*******************************************************************
// ilEuclidNorm
//   normalizes vectors of dim=n in mxn input matrix with the
//   Euclidean norm
//*******************************************************************
void ilEuclidNorm(pMat const& src, pMat dst)
{
    int m = src->rows;
    int n = src->cols;
    int type = src->type;
    pMat ones = CreateMat(n, 1, type);
    pMat res1 = CreateMat(m, n, type);
    pMat norm = CreateMat(m, 1, type);
    SetValue(ones, cvScalar(1.0));

    //*** compute the norm
    Multiply(src, src, res1);
    MatrixMultiply(res1, ones, norm);
    PowerMatrix(norm, norm, .5);

    //*** normalize columns of src
#if 0 //*** matrix version
    pMat normmat = CreateMat(m, n, CV_32FC1);
    pMat onesrow = CreateMat(1, n, CV_32FC1);
    SetValue(onesrow, cvScalar(1.0));
    MatrixMultiply(norm, onesrow, normmat);
    Divide(src, normmat, dst);
#endif

#if 1 // *** column version
    CvMat colmat1 = cvMat(0, 0, 0, 0);
    CvMat colmat2 = cvMat(0, 0, 0, 0);
    for (int i = 0; i<n; ++i)
    {
        cvGetCol(src.get(), &colmat1, i);
        cvGetCol(dst.get(), &colmat2, i);
        Divide(dummyGuard(&colmat1), norm, dummyGuard(&colmat2));
    }
#endif
}
コード例 #2
0
ファイル: OCR.cpp プロジェクト: AAAyag/OCR-1
/// <summary>
///     Finds min and max X of the data present in given image.
/// </summary>
/// <params name="imsSrc">
///     Source image for which min and max X has to be found.
/// </params>
/// <params name="min">
///     Int pointer where the min X has to saved.
/// </params>
/// <params name="max">
///     Int pointer where the max X has to saved.
/// </params>
/// <returns> Nothing. </returns>
void OCR::findX(IplImage* imgSrc,int* min, int* max)
{
	int i;
	int minFound=0;
	CvMat data;
	CvScalar maxVal=cvRealScalar(imgSrc->height * 255);
	CvScalar val=cvRealScalar(0);
	//For each col sum, if sum < width*255 then we find the min
	//then continue to end to search the max, if sum< width*255 then is new max
	for (i=0; i< imgSrc->width; i++)
	{
	    val = cvRealScalar(0);
		cvGetCol(imgSrc, &data, i);
		val= cvSum(&data);
		if(val.val[0] < maxVal.val[0])
		{
			*max= i;
			if(!minFound)
			{
				*min= i;
				minFound= 1;
			}

		}
	}
}
コード例 #3
0
ファイル: AAM_TDM.cpp プロジェクト: 2php/aamlibrary
//============================================================================
void AAM_TDM::CalcMeanTexture(const CvMat* AllTextures, CvMat* meanTexture)
{
	CvMat submat;
	for(int i = 0; i < meanTexture->cols; i++)
	{
		cvGetCol(AllTextures, &submat, i);
		cvmSet(meanTexture, 0, i, cvAvg(&submat).val[0]);
	}
}
コード例 #4
0
ファイル: Kalman.cpp プロジェクト: tzwenn/alvar
void KalmanSensorEkf::update_H(CvMat *x_pred) {
	// By default we update the H by calculating Jacobian numerically
	const double step = 0.000001;
	cvZero(H);
	for (int i=0; i<n; i++) {
		CvMat H_column;
		cvGetCol(H, &H_column, i);

		cvZero(delta); 
		cvmSet(delta, i, 0, step);
		cvAdd(x_pred, delta, x_plus);
		cvmSet(delta, i, 0, -step);
		cvAdd(x_pred, delta, x_minus);

		h(x_plus, z_tmp1);  
		h(x_minus, z_tmp2);	
		cvSub(z_tmp1, z_tmp2, &H_column);
		cvScale(&H_column, &H_column, 1.0/(2*step));
	}
}
コード例 #5
0
ファイル: Kalman.cpp プロジェクト: tzwenn/alvar
void KalmanEkf::update_F(unsigned long tick) {
	// By default we update the F by calculating Jacobian numerically
	// TODO
	double dt = (tick-prev_tick)/1000.0;
	const double step = 0.000001;
	cvZero(F);
	for (int i=0; i<n; i++) {
		CvMat F_column;
		cvGetCol(F, &F_column, i);

		cvZero(delta); 
		cvmSet(delta, i, 0, step);
		cvAdd(x, delta, x_plus);
		cvmSet(delta, i, 0, -step);
		cvAdd(x, delta, x_minus);

		f(x_plus, x_tmp1, dt);  
		f(x_minus, x_tmp2, dt);	
		cvSub(x_tmp1, x_tmp2, &F_column);
		cvScale(&F_column, &F_column, 1.0/(2*step));
	}
}
コード例 #6
0
int CFaceMngr::NormFaceRecog( CvMat *faceImg32 )
{
	feature->GetFeature(faceImg32, tfeature);
	ss->Project(tfeature, tmodel);

	double	minDist = 1e9, curVal; // minDist should be among -1~1 for angle metric
	int curMatch = 0;
	CvMat col;

	// 试图向Matlab那样用矩阵操作,把tmodel Repeat成矩阵,然后Mul,Reduce,MinMaxLoc,发现反倒略慢,所以还是用循环
	for (int i = 0; i < m_trainNum; i++) 
	{
		cvGetCol(m_models, &col, i);
		curVal = ss->CalcVectorDist(&col, tmodel);
		if (curVal < minDist)
		{
			minDist = curVal;
			curMatch = i;
		}
	}

	return trainIds[curMatch];
}
コード例 #7
0
const CvMat* CvMLData::get_responses()
{
    CV_FUNCNAME( "CvMLData::get_responses_ptr" );
    __BEGIN__;

    int var_count = 0;

    if ( !values )
        CV_ERROR( CV_StsInternal, "data is empty" );
    var_count = values->cols;

    if ( response_idx < 0 || response_idx >= var_count )
       return 0;
    if ( !response_out )
        response_out = cvCreateMatHeader( values->rows, 1, CV_32FC1 );
    else
        cvInitMatHeader( response_out, values->rows, 1, CV_32FC1);
    cvGetCol( values, response_out, response_idx );

    __END__;

    return response_out;
}
コード例 #8
0
ファイル: savgol.cpp プロジェクト: xufango/contrib_bk
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
CvMat *tgso (CvMat &tmap, int ntex, double sigma, double theta, CvMat &tsim, int useChi2) {


	CvMat *roundTmap=cvCreateMat(tmap.rows,tmap.cols,CV_32FC1);
	CvMat *comp=cvCreateMat(tmap.rows,tmap.cols,CV_32FC1);

	for (int i=0;i<tmap.rows;i++)
		for (int j=0;j<tmap.cols;j++)
			cvSetReal2D(roundTmap,i,j,cvRound(cvGetReal2D(&tmap,i,j)));

	cvSub(&tmap,roundTmap,comp);
	if (cvCountNonZero(comp)) {
		printf("texton labels not integral");
		cvReleaseMat(&roundTmap);
		cvReleaseMat(&comp);
		exit(1);
	}

	double min,max;
	cvMinMaxLoc(&tmap,&min,&max);
	if (min<1 && max>ntex) {
		char *msg=new char[50];
		printf(msg,"texton labels out of range [1,%d]",ntex);
		cvReleaseMat(&roundTmap);
		cvReleaseMat(&comp);
		exit(1);
	}

	cvReleaseMat(&roundTmap);
	cvReleaseMat(&comp);


	double wr=floor(sigma); //sigma=radius (Leo) 

	CvMat *x=cvCreateMat(1,wr-(-wr)+1, CV_64FC1);
	CvMat *y=cvCreateMat(wr-(-wr)+1,1, CV_64FC1);

	CvMat *u=cvCreateMat(wr-(-wr)+1,wr-(-wr)+1, CV_64FC1);
	CvMat *v=cvCreateMat(wr-(-wr)+1,wr-(-wr)+1, CV_64FC1);
	CvMat *gamma=cvCreateMat(u->rows,v->rows, CV_64FC1);

	// Set x,y directions 
	for (int j=-wr;j<=wr;j++) {
		cvSetReal2D(x,0,(j+wr),j);
		cvSetReal2D(y,(j+wr),0,j);
	}

	// Set u,v, meshgrids
	for (int i=0;i<u->rows;i++) {
		cvRepeat(x,u);
		cvRepeat(y,v);
	}

	// Compute the gamma matrix from the grid
	for (int i=0;i<u->rows;i++) 
		for (int j=0;j<u->cols;j++)
			cvSetReal2D(gamma,i,j,atan2(cvGetReal2D(v,i,j),cvGetReal2D(u,i,j)));

	cvReleaseMat(&x);
	cvReleaseMat(&y);

	CvMat *sum=cvCreateMat(u->rows,u->cols, CV_64FC1);
	cvMul(u,u,u);
	cvMul(v,v,v);
	cvAdd(u,v,sum);
	CvMat *mask=cvCreateMat(u->rows,u->cols, CV_8UC1);
	cvCmpS(sum,sigma*sigma,mask,CV_CMP_LE);
	cvConvertScale(mask,mask,1.0/255);
	cvSetReal2D(mask,wr,wr,0);
	int count=cvCountNonZero(mask);

	cvReleaseMat(&u);
	cvReleaseMat(&v);
	cvReleaseMat(&sum);

	CvMat *sub=cvCreateMat(mask->rows,mask->cols, CV_64FC1);
	CvMat *side=cvCreateMat(mask->rows,mask->cols, CV_8UC1);

	cvSubS(gamma,cvScalar(theta),sub);
	cvReleaseMat(&gamma);

	for (int i=0;i<mask->rows;i++){
		for (int j=0;j<mask->cols;j++) {
			double n=cvmGet(sub,i,j);
			double n_mod = n-floor(n/(2*M_PI))*2*M_PI;
			cvSetReal2D(side,i,j, 1 + int(n_mod < M_PI));
		}
	}

	cvMul(side,mask,side);
	cvReleaseMat(&sub);
	cvReleaseMat(&mask);

	CvMat *lmask=cvCreateMat(side->rows,side->cols, CV_8UC1);
	CvMat *rmask=cvCreateMat(side->rows,side->cols, CV_8UC1);
	cvCmpS(side,1,lmask,CV_CMP_EQ);
	cvCmpS(side,2,rmask,CV_CMP_EQ);
	int count1=cvCountNonZero(lmask), count2=cvCountNonZero(rmask);
	if (count1 != count2) {
		printf("Bug: imbalance\n");
	}

	CvMat *rlmask=cvCreateMat(side->rows,side->cols, CV_32FC1);
	CvMat *rrmask=cvCreateMat(side->rows,side->cols, CV_32FC1);
	cvConvertScale(lmask,rlmask,1.0/(255*count)*2);
	cvConvertScale(rmask,rrmask,1.0/(255*count)*2);


	cvReleaseMat(&lmask);
	cvReleaseMat(&rmask);
	cvReleaseMat(&side);

	int h=tmap.rows;
	int w=tmap.cols;


	CvMat *d       = cvCreateMat(h*w,ntex,CV_32FC1);
	CvMat *coltemp = cvCreateMat(h*w,1,CV_32FC1);
	CvMat *tgL     = cvCreateMat(h,w, CV_32FC1);
	CvMat *tgR     = cvCreateMat(h,w, CV_32FC1);
	CvMat *temp    = cvCreateMat(h,w,CV_8UC1);
	CvMat *im      = cvCreateMat(h,w, CV_32FC1);
	CvMat *sub2    = cvCreateMat(h,w,CV_32FC1);
	CvMat *sub2t   = cvCreateMat(w,h,CV_32FC1);
	CvMat *prod    = cvCreateMat(h*w,ntex,CV_32FC1);
	CvMat reshapehdr,*reshape;

	CvMat* tgL_pad = cvCreateMat(h+rlmask->rows-1,w+rlmask->cols-1,CV_32FC1);
	CvMat* tgR_pad = cvCreateMat(h+rlmask->rows-1,w+rlmask->cols-1,CV_32FC1);
	CvMat* im_pad  = cvCreateMat(h+rlmask->rows-1,w+rlmask->cols-1,CV_32FC1);

	CvMat *tg=cvCreateMat(h,w,CV_32FC1);
	cvZero(tg);
	
	if (useChi2 == 1){
		CvMat* temp_add1 = cvCreateMat(h,w,CV_32FC1);
		for (int i=0;i<ntex;i++) {
			cvCmpS(&tmap,i+1,temp,CV_CMP_EQ); 
			cvConvertScale(temp,im,1.0/255);

			cvCopyMakeBorder(tgL,tgL_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT);
			cvCopyMakeBorder(tgR,tgR_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT);
			cvCopyMakeBorder(im,im_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT);

			cvFilter2D(im_pad,tgL_pad,rlmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2));
			cvFilter2D(im_pad,tgR_pad,rrmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2));

			cvGetSubRect(tgL_pad,tgL,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgL->cols,tgL->rows));
			cvGetSubRect(tgR_pad,tgR,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgR->cols,tgR->rows));

			cvSub(tgL,tgR,sub2);
			cvPow(sub2,sub2,2.0);
			cvAdd(tgL,tgR,temp_add1);
			cvAddS(temp_add1,cvScalar(0.0000000001),temp_add1);
			cvDiv(sub2,temp_add1,sub2);
			cvAdd(tg,sub2,tg);
		}
		cvScale(tg,tg,0.5);

		cvReleaseMat(&temp_add1);

	}
	else{// if not chi^2
		for (int i=0;i<ntex;i++) {
			cvCmpS(&tmap,i+1,temp,CV_CMP_EQ); 
			cvConvertScale(temp,im,1.0/255);

			cvCopyMakeBorder(tgL,tgL_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT);
			cvCopyMakeBorder(tgR,tgR_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT);
			cvCopyMakeBorder(im,im_pad,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2),IPL_BORDER_CONSTANT);

			cvFilter2D(im_pad,tgL_pad,rlmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2));
			cvFilter2D(im_pad,tgR_pad,rrmask,cvPoint((rlmask->cols-1)/2,(rlmask->rows-1)/2));

			cvGetSubRect(tgL_pad,tgL,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgL->cols,tgL->rows));
			cvGetSubRect(tgR_pad,tgR,cvRect((rlmask->cols-1)/2,(rlmask->rows-1)/2,tgR->cols,tgR->rows));

			cvSub(tgL,tgR,sub2);
			cvAbs(sub2,sub2);
			cvTranspose(sub2,sub2t);
			reshape=cvReshape(sub2t,&reshapehdr,0,h*w);
			cvGetCol(d,coltemp,i);
			cvCopy(reshape,coltemp);
		}

		cvMatMul(d,&tsim,prod);
		cvMul(prod,d,prod);


		CvMat *sumcols=cvCreateMat(h*w,1,CV_32FC1);
		cvSetZero(sumcols);
		for (int i=0;i<prod->cols;i++) {
			cvGetCol(prod,coltemp,i);
			cvAdd(sumcols,coltemp,sumcols);
		}

		reshape=cvReshape(sumcols,&reshapehdr,0,w);
		cvTranspose(reshape,tg);

		cvReleaseMat(&sumcols);
	}


	//Smooth the gradient now!!
	tg=fitparab(*tg,sigma,sigma/4,theta);
	cvMaxS(tg,0,tg); 

	
	cvReleaseMat(&im_pad);
	cvReleaseMat(&tgL_pad);
	cvReleaseMat(&tgR_pad);
	cvReleaseMat(&rlmask);
	cvReleaseMat(&rrmask);
	cvReleaseMat(&im);
	cvReleaseMat(&tgL);
	cvReleaseMat(&tgR);
	cvReleaseMat(&temp);
	cvReleaseMat(&coltemp);
	cvReleaseMat(&sub2);
	cvReleaseMat(&sub2t);
	cvReleaseMat(&d);
	cvReleaseMat(&prod);

	return tg;

}
コード例 #9
0
ファイル: core_core_c.h.cpp プロジェクト: zackboll/opencvada
 CvMat * cvGetCol_wrap(const CvArr * arr , CvMat * submat , int col ){
	return cvGetCol(/*const*//*CvArr*//***/arr , /*CvMat*//***/submat , /*int*/col);
}
コード例 #10
0
bool
cvFindExtrinsicCameraParams3( const CvMat* obj_points,
                  const CvMat* img_points, const CvMat* A,
                  const CvMat* dist_coeffs,
                  CvMat* r_vec, CvMat* t_vec )
{
    bool fGood = true;

    const int max_iter = 20;
    CvMat *_M = 0, *_Mxy = 0, *_m = 0, *_mn = 0, *_L = 0, *_J = 0;
    
    CV_FUNCNAME( "cvFindExtrinsicCameraParams3" );

    __BEGIN__;

    int i, j, count;
    double a[9], k[4] = { 0, 0, 0, 0 }, R[9], ifx, ify, cx, cy;
    double Mc[3] = {0, 0, 0}, MM[9], U[9], V[9], W[3];
    double JtJ[6*6], JtErr[6], JtJW[6], JtJV[6*6], delta[6], param[6];
    CvPoint3D64f* M = 0;
    CvPoint2D64f *m = 0, *mn = 0;
    CvMat _a = cvMat( 3, 3, CV_64F, a );
    CvMat _R = cvMat( 3, 3, CV_64F, R );
    CvMat _r = cvMat( 3, 1, CV_64F, param );
    CvMat _t = cvMat( 3, 1, CV_64F, param + 3 );
    CvMat _Mc = cvMat( 1, 3, CV_64F, Mc );
    CvMat _MM = cvMat( 3, 3, CV_64F, MM );
    CvMat _U = cvMat( 3, 3, CV_64F, U );
    CvMat _V = cvMat( 3, 3, CV_64F, V );
    CvMat _W = cvMat( 3, 1, CV_64F, W );
    CvMat _JtJ = cvMat( 6, 6, CV_64F, JtJ );
    CvMat _JtErr = cvMat( 6, 1, CV_64F, JtErr );
    CvMat _JtJW = cvMat( 6, 1, CV_64F, JtJW );
    CvMat _JtJV = cvMat( 6, 6, CV_64F, JtJV );
    CvMat _delta = cvMat( 6, 1, CV_64F, delta );
    CvMat _param = cvMat( 6, 1, CV_64F, param );
    CvMat _dpdr, _dpdt;

    if( !CV_IS_MAT(obj_points) || !CV_IS_MAT(img_points) ||
        !CV_IS_MAT(A) || !CV_IS_MAT(r_vec) || !CV_IS_MAT(t_vec) )
        CV_ERROR( CV_StsBadArg, "One of required arguments is not a valid matrix" );

    count = MAX(obj_points->cols, obj_points->rows);
    CV_CALL( _M = cvCreateMat( 1, count, CV_64FC3 ));
    CV_CALL( _Mxy = cvCreateMat( 1, count, CV_64FC2 ));
    CV_CALL( _m = cvCreateMat( 1, count, CV_64FC2 ));
    CV_CALL( _mn = cvCreateMat( 1, count, CV_64FC2 ));
    M = (CvPoint3D64f*)_M->data.db;
    m = (CvPoint2D64f*)_m->data.db;
    mn = (CvPoint2D64f*)_mn->data.db;

    CV_CALL( cvConvertPointsHomogenious( obj_points, _M ));
    CV_CALL( cvConvertPointsHomogenious( img_points, _m ));
    CV_CALL( cvConvert( A, &_a ));

    if( dist_coeffs )
    {
        CvMat _k;
        if( !CV_IS_MAT(dist_coeffs) ||
            CV_MAT_DEPTH(dist_coeffs->type) != CV_64F &&
            CV_MAT_DEPTH(dist_coeffs->type) != CV_32F ||
            dist_coeffs->rows != 1 && dist_coeffs->cols != 1 ||
            dist_coeffs->rows*dist_coeffs->cols*CV_MAT_CN(dist_coeffs->type) != 4 )
            CV_ERROR( CV_StsBadArg,
                "Distortion coefficients must be 1x4 or 4x1 floating-point vector" );

        _k = cvMat( dist_coeffs->rows, dist_coeffs->cols,
                    CV_MAKETYPE(CV_64F,CV_MAT_CN(dist_coeffs->type)), k );
        CV_CALL( cvConvert( dist_coeffs, &_k ));
    }

    if( CV_MAT_DEPTH(r_vec->type) != CV_64F && CV_MAT_DEPTH(r_vec->type) != CV_32F ||
        r_vec->rows != 1 && r_vec->cols != 1 ||
        r_vec->rows*r_vec->cols*CV_MAT_CN(r_vec->type) != 3 )
        CV_ERROR( CV_StsBadArg, "Rotation vector must be 1x3 or 3x1 floating-point vector" );

    if( CV_MAT_DEPTH(t_vec->type) != CV_64F && CV_MAT_DEPTH(t_vec->type) != CV_32F ||
        t_vec->rows != 1 && t_vec->cols != 1 ||
        t_vec->rows*t_vec->cols*CV_MAT_CN(t_vec->type) != 3 )
        CV_ERROR( CV_StsBadArg,
            "Translation vector must be 1x3 or 3x1 floating-point vector" );

    ifx = 1./a[0]; ify = 1./a[4];
    cx = a[2]; cy = a[5];

    // normalize image points
    // (unapply the intrinsic matrix transformation and distortion)
    for( i = 0; i < count; i++ )
    {
        double x = (m[i].x - cx)*ifx, y = (m[i].y - cy)*ify, x0 = x, y0 = y;

        // compensate distortion iteratively
        if( dist_coeffs )
            for( j = 0; j < 5; j++ )
            {
                double r2 = x*x + y*y;
                double icdist = 1./(1 + k[0]*r2 + k[1]*r2*r2);
                double delta_x = 2*k[2]*x*y + k[3]*(r2 + 2*x*x);
                double delta_y = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y;
                x = (x0 - delta_x)*icdist;
                y = (y0 - delta_y)*icdist;
            }
        mn[i].x = x; mn[i].y = y;

        // calc mean(M)
        Mc[0] += M[i].x;
        Mc[1] += M[i].y;
        Mc[2] += M[i].z;
    }

    Mc[0] /= count;
    Mc[1] /= count;
    Mc[2] /= count;

    cvReshape( _M, _M, 1, count );
    cvMulTransposed( _M, &_MM, 1, &_Mc );
    cvSVD( &_MM, &_W, 0, &_V, CV_SVD_MODIFY_A + CV_SVD_V_T );

    // initialize extrinsic parameters
    if( W[2]/W[1] < 1e-3 || count < 4 )
    {
        // a planar structure case (all M's lie in the same plane)
        double tt[3], h[9], h1_norm, h2_norm;
        CvMat* R_transform = &_V;
        CvMat T_transform = cvMat( 3, 1, CV_64F, tt );
        CvMat _H = cvMat( 3, 3, CV_64F, h );
        CvMat _h1, _h2, _h3;

        if( V[2]*V[2] + V[5]*V[5] < 1e-10 )
            cvSetIdentity( R_transform );

        if( cvDet(R_transform) < 0 )
            cvScale( R_transform, R_transform, -1 );

        cvGEMM( R_transform, &_Mc, -1, 0, 0, &T_transform, CV_GEMM_B_T );

        for( i = 0; i < count; i++ )
        {
            const double* Rp = R_transform->data.db;
            const double* Tp = T_transform.data.db;
            const double* src = _M->data.db + i*3;
            double* dst = _Mxy->data.db + i*2;

            dst[0] = Rp[0]*src[0] + Rp[1]*src[1] + Rp[2]*src[2] + Tp[0];
            dst[1] = Rp[3]*src[0] + Rp[4]*src[1] + Rp[5]*src[2] + Tp[1];
        }

        cvFindHomography( _Mxy, _mn, &_H );

        cvGetCol( &_H, &_h1, 0 );
        _h2 = _h1; _h2.data.db++;
        _h3 = _h2; _h3.data.db++;
        h1_norm = sqrt(h[0]*h[0] + h[3]*h[3] + h[6]*h[6]);
        h2_norm = sqrt(h[1]*h[1] + h[4]*h[4] + h[7]*h[7]);

        cvScale( &_h1, &_h1, 1./h1_norm );
        cvScale( &_h2, &_h2, 1./h2_norm );
        cvScale( &_h3, &_t, 2./(h1_norm + h2_norm));
        cvCrossProduct( &_h1, &_h2, &_h3 );

        cvRodrigues2( &_H, &_r );
        cvRodrigues2( &_r, &_H );
        cvMatMulAdd( &_H, &T_transform, &_t, &_t );
        cvMatMul( &_H, R_transform, &_R );
        cvRodrigues2( &_R, &_r );
    }
    else
    {
        // non-planar structure. Use DLT method
        double* L;
        double LL[12*12], LW[12], LV[12*12], sc;
        CvMat _LL = cvMat( 12, 12, CV_64F, LL );
        CvMat _LW = cvMat( 12, 1, CV_64F, LW );
        CvMat _LV = cvMat( 12, 12, CV_64F, LV );
        CvMat _RRt, _RR, _tt;

        CV_CALL( _L = cvCreateMat( 2*count, 12, CV_64F ));
        L = _L->data.db;

        for( i = 0; i < count; i++, L += 24 )
        {
            double x = -mn[i].x, y = -mn[i].y;
            L[0] = L[16] = M[i].x;
            L[1] = L[17] = M[i].y;
            L[2] = L[18] = M[i].z;
            L[3] = L[19] = 1.;
            L[4] = L[5] = L[6] = L[7] = 0.;
            L[12] = L[13] = L[14] = L[15] = 0.;
            L[8] = x*M[i].x;
            L[9] = x*M[i].y;
            L[10] = x*M[i].z;
            L[11] = x;
            L[20] = y*M[i].x;
            L[21] = y*M[i].y;
            L[22] = y*M[i].z;
            L[23] = y;
        }

        cvMulTransposed( _L, &_LL, 1 );
        cvSVD( &_LL, &_LW, 0, &_LV, CV_SVD_MODIFY_A + CV_SVD_V_T );
        _RRt = cvMat( 3, 4, CV_64F, LV + 11*12 );
        cvGetCols( &_RRt, &_RR, 0, 3 );
        cvGetCol( &_RRt, &_tt, 3 );
        if( cvDet(&_RR) < 0 )
            cvScale( &_RRt, &_RRt, -1 );
        sc = cvNorm(&_RR);
        cvSVD( &_RR, &_W, &_U, &_V, CV_SVD_MODIFY_A + CV_SVD_U_T + CV_SVD_V_T );
        cvGEMM( &_U, &_V, 1, 0, 0, &_R, CV_GEMM_A_T );
        cvScale( &_tt, &_t, cvNorm(&_R)/sc );
        cvRodrigues2( &_R, &_r );
        cvReleaseMat( &_L );
    }

    //
    // Check if new r and t are good
    //
    if ( cvGetReal1D( r_vec, 0 ) ||
         cvGetReal1D( r_vec, 1 ) ||
         cvGetReal1D( r_vec, 2 ) ||
         cvGetReal1D( t_vec, 0 ) ||
         cvGetReal1D( t_vec, 1 ) ||
         cvGetReal1D( t_vec, 2 ) )
    {
        //
        // perfom this only when the old r and t exist.
        //
        CvMat * R_inv = cvCreateMat( 3, 3, CV_64FC1 );
        CvMat * r_old = cvCreateMat( 3, 1, CV_64FC1 );
        CvMat * R_old = cvCreateMat( 3, 3, CV_64FC1 );
        CvMat * t_old = cvCreateMat( 3, 1, CV_64FC1 );
        // get new center
        cvInvert( &_R, R_inv );
        double new_center[3];
        CvMat newCenter = cvMat( 3, 1, CV_64FC1, new_center );
        cvMatMul( R_inv, &_t, &newCenter );
        cvScale( &newCenter, &newCenter, -1 );
        // get old center
        cvConvert( r_vec, r_old );
        cvConvert( t_vec, t_old );
        cvRodrigues2( r_old, R_old );
        cvInvert( R_old, R_inv );
        double old_center[3];
        CvMat oldCenter = cvMat( 3, 1, CV_64FC1, old_center );
        cvMatMul( R_inv, t_old, &oldCenter );
        cvScale( &oldCenter, &oldCenter, -1 );
        // get difference
        double diff_center = 0;
        for ( int i = 0; i < 3 ; i ++ )
            diff_center += pow( new_center[i] - old_center[i], 2 );
        diff_center = sqrt( diff_center );
        if ( diff_center > 300 )
        {
            printf("diff_center = %.2f --> set initial r and t as same as  the previous\n", diff_center);
            cvConvert(r_vec, &_r);
            cvConvert(t_vec, &_t);
            fGood = false;
        }
//        else printf("diff_center = %.2f\n", diff_center );
        
        cvReleaseMat( &R_inv );
        cvReleaseMat( &r_old );
        cvReleaseMat( &R_old );
        cvReleaseMat( &t_old );
    }
    
    if ( fGood )
    {
        CV_CALL( _J = cvCreateMat( 2*count, 6, CV_64FC1 ));
        cvGetCols( _J, &_dpdr, 0, 3 );
        cvGetCols( _J, &_dpdt, 3, 6 );

        // refine extrinsic parameters using iterative algorithm
        for( i = 0; i < max_iter; i++ )
        {
            double n1, n2;
            cvReshape( _mn, _mn, 2, 1 );
            cvProjectPoints2( _M, &_r, &_t, &_a, dist_coeffs,
                              _mn, &_dpdr, &_dpdt, 0, 0, 0 );
            cvSub( _m, _mn, _mn );
            cvReshape( _mn, _mn, 1, 2*count );

            cvMulTransposed( _J, &_JtJ, 1 );
            cvGEMM( _J, _mn, 1, 0, 0, &_JtErr, CV_GEMM_A_T );
            cvSVD( &_JtJ, &_JtJW, 0, &_JtJV, CV_SVD_MODIFY_A + CV_SVD_V_T );
            if( JtJW[5]/JtJW[0] < 1e-12 )
                break;
            cvSVBkSb( &_JtJW, &_JtJV, &_JtJV, &_JtErr,
                      &_delta, CV_SVD_U_T + CV_SVD_V_T );
            cvAdd( &_delta, &_param, &_param );
            n1 = cvNorm( &_delta );
            n2 = cvNorm( &_param );
            if( n1/n2 < 1e-10 )
                break;
        }

        _r = cvMat( r_vec->rows, r_vec->cols,
            CV_MAKETYPE(CV_64F,CV_MAT_CN(r_vec->type)), param );
        _t = cvMat( t_vec->rows, t_vec->cols,
            CV_MAKETYPE(CV_64F,CV_MAT_CN(t_vec->type)), param + 3 );

        cvConvert( &_r, r_vec );
        cvConvert( &_t, t_vec );
    }

    __END__;

    cvReleaseMat( &_M );
    cvReleaseMat( &_Mxy );
    cvReleaseMat( &_m );
    cvReleaseMat( &_mn );
    cvReleaseMat( &_L );
    cvReleaseMat( &_J );

    return fGood;
}
コード例 #11
0
ファイル: orl_func.cpp プロジェクト: FlynnShek/facerecog
double CFaceMngr::run_orl( LPCTSTR rp, vector<SFInfo> & trainList, vector<SFInfo> & testList, int * resultList )
{

/* 预处理 */
	cvReleaseMat(&m_models);
	delete []trainIds;
	cout<<"Computing Feature...\t";
	tic();


/* 初始化 */
	m_trainNum = trainList.size();
	CvMat *fts = cvCreateMat(m_featureSz, m_trainNum, CV_FT_FC1);
	CvMat col;

	CString strRp = rp;
	int idx = 0;
	trainIds = new int[m_trainNum];


/* 读入图像并转化为原始特征 */
	sfi_iter iter = trainList.begin();
	for (; iter != trainList.end(); iter++)
	{
		IplImage *img = cvLoadImage(strRp+iter->picPath, CV_LOAD_IMAGE_GRAYSCALE);
		cvResize(img, tfaceImg8, CV_INTER_NN);
		cvConvertScale(tfaceImg8, tfaceImg32, 1.0/255); // orl不用归一化
		cvGetCol(fts, &col, idx);
		feature->GetFeature(tfaceImg32, &col);
		trainIds[idx++] = iter->classId;
		cvReleaseImage(&img);
	}


/* 训练 */
	double t1 = toc();
	cout<<t1<<"s"<<endl<<"Training...\t";
	ss->Train(fts, trainIds);
	m_modelSz = ss->GetSubspaceDim();
	tmodel = cvCreateMat(m_modelSz, 1, CV_MODEL_FC1);


/* 投影得到模板矩阵 */
	m_models = cvCreateMat(m_modelSz, m_trainNum, CV_MODEL_FC1);
	ss->Project(fts, m_models);
	cvReleaseMat(&fts);
	double t2 = toc();
	cout<<t2-t1<<"s"<<endl<<"Recognizing...\t";


/* 识别 */
	int correctNum = 0;
	idx = 0;
	iter = testList.begin();
	for (; iter != testList.end(); iter++)
	{
		IplImage *img = cvLoadImage(strRp + iter->picPath, CV_LOAD_IMAGE_GRAYSCALE);
		cvResize(img, tfaceImg8, CV_INTER_NN);
		cvConvertScale(tfaceImg8, tfaceImg32, 1.0/255);
		resultList[idx] = NormFaceRecog(tfaceImg32);
		if (resultList[idx++] == iter->classId)
			correctNum++;
		cvReleaseImage(&img);
	}


/* OK */
	double t3 = toc();
	cout<<t3-t2<<"s"<<endl;
	return (double)correctNum / testList.size();
}
コード例 #12
0
CvMat* vgg_X_from_xP_nonlin(CvMat* u1, CvMat** P1, CvMat* imsize1, int K)
{

	CvMat* u;
	CvMat** P=new CvMat* [K];
	CvMat* imsize;
	
	u=cvCreateMat(u1->rows,u1->cols,u1->type);
	cvCopy(u1,u);

	int kp;
	for(kp=0;kp<K;kp++)
	{
		P[kp]=cvCreateMat(P1[kp]->rows,P1[kp]->cols,P1[kp]->type);
		cvCopy(P1[kp],P[kp]);
	}

	imsize=cvCreateMat(imsize1->rows,imsize1->cols,imsize1->type);
	cvCopy(imsize1,imsize);


	CvMat* X;
	CvMat* H;
	CvMat* u_2_rows;
	CvMat* W;
	CvMat* U;
	CvMat* T;
	CvMat* Y;
	CvMat** Q=new CvMat*[K];//Q is a variable not well defined
	
	CvMat* J;
	CvMat* e;
	CvMat* J_tr;
	CvMat* eprev;
	CvMat* JtJ;
	CvMat* Je;
	CvMat* Y_new;

	CvMat* T_2_cols;
	CvMat* T_rest_cols;
	CvMat* X_T;
	CvScalar f, inf;
	int i, mat_id;
	int u_rows = u->rows;
	int u_cols = u->cols;
	double lambda_min, lambda_max;
	CvMat* imsize_col = cvCreateMat(2, 1, CV_64FC1);

	/* K is the number of images */
	if(K < 2)
	{
		printf("\n Cannot reconstruct 3D from 1 image");
		return 0;
	}

	/* Create temporary matrix for the linear function */
	u_2_rows = cvCreateMat(2, u_cols, CV_64FC1);

	/* Initialize the temporary matrix by extracting the first two rows */
	u_2_rows = cvGetRows(u, u_2_rows, 0, 2, 1);

	/* Call the linear function */
	X = vgg_X_from_xP_lin(u_2_rows, P, K, imsize);

	imsize_col = cvGetCol(imsize, imsize_col, 0);
	f = cvSum(imsize_col);
	f.val[0] = 4 / f.val[0];

	/* Create and initialize H matrix */
	H = cvCreateMat(3, 3, CV_64FC1);

	H->data.db[0] = f.val[0];
	H->data.db[1] = 0;
	H->data.db[2] = ((-1) * f.val[0] * cvmGet(imsize, 0, 0)) / 2;
	H->data.db[3] = 0;
	H->data.db[4] = f.val[0];
	H->data.db[5] = ((-1) * f.val[0] * cvmGet(imsize, 1, 0)) / 2;
	H->data.db[6] = 0;
	H->data.db[7] = 0;
	H->data.db[8] = 1;

	for(mat_id = 0; mat_id < K ; mat_id++)
	{
		cvMatMul(H, P[mat_id], P[mat_id]);
	}
	/* u = H * u; */
	cvMatMul(H, u, u);
	/*
	//debug
	printf("....H\n");
	CvMat_printdb(stdout,"%7.3f ",H);
	//debug
	printf("....u\n");
	CvMat_printdb(stdout,"%7.3f ",u);
	*/

	/* Parametrize X such that X = T*[Y;1]; thus x = P*T*[Y;1] = Q*[Y;1] */
	/* Create the SVD matrices X = U*W*V'*/

	X_T = cvCreateMat(X->cols, X->rows, CV_64FC1); /* M * N */
	W = cvCreateMat(X_T->rows, X_T->cols, CV_64FC1); /* M * N */
	U = cvCreateMat(X_T->rows, X_T->rows, CV_64FC1); /* M * M */
	T = cvCreateMat(X_T->cols, X_T->cols, CV_64FC1); /* N * N */
	cvTranspose(X, X_T);
	cvSVD(X_T, W, U, T);


	cvReleaseMat(&W);
	
	/* T = T(:,[2:end 1]); */
	/* Initialize the temporary matrix by extracting the first two columns */
	/* Create temporary matrix for the linear function */
	T_2_cols    = cvCreateMat(T->rows, 2, CV_64FC1);
	T_rest_cols = cvCreateMat(T->rows, (T->cols - 2), CV_64FC1);

	/* Initialize the temporary matrix by extracting the first two columns */
	T_2_cols= sfmGetCols(T,0,0);
	T_rest_cols=sfmGetCols(T,1,T->cols-1);

	T=sfmAlignMatH(T_rest_cols,T_2_cols);

	for(mat_id = 0; mat_id < K ; mat_id++)
	{
	    /* Create temporary matrix for the linear function */
	    Q[mat_id] = cvCreateMat(P[mat_id]->rows, T->cols, CV_64FC1);
		cvMatMul(P[mat_id], T, Q[mat_id]);
	}

	/*
	//debug
	printf("....Q0\n");
	CvMat_printdb(stdout,"%7.3f ",Q[0]);

	//debug
	printf("....Q1\n");
	CvMat_printdb(stdout,"%7.3f ",Q[1]);
*/
	/* Newton estimation */
	/* Create the required Y matrix for the Newton process */
	Y = cvCreateMat(3, 1, CV_64FC1);
	cvSetZero(Y); /* Y = [0;0;0] */

	/* Initialize the infinite array */
	inf.val[0] = INF;
	inf.val[1] = INF;
	inf.val[2] = INF;
	inf.val[3] = INF;
	eprev = cvCreateMat(1, 1, CV_64FC1); 
	cvSet(eprev, inf, 0);

	for(i = 0 ; i < 10 ; i++)
	{
	//	printf("i=%d....\n",i);
		int pass;
		double RCondVal;

		//initialize e,J before using.

		e=cvCreateMat(2*K,1,CV_64FC1);
		J=cvCreateMat(2*K,3,CV_64FC1);

		pass = resid(Y, u, Q, K, e, J);

		J_tr = cvCreateMat(J->cols, J->rows, CV_64FC1);
		cvTranspose(J, J_tr);

		JtJ = cvCreateMat(J->cols, J->cols, CV_64FC1);
		cvMatMul(J_tr, J, JtJ);

		//prevent memory leak;
		cvReleaseMat(&W);

		/* Create the SVD matrices JtJ = U*W*V'*/
		W = cvCreateMat(J->cols, J->cols, CV_64FC1); 

		cvSVD(JtJ, W); 
		/*
		//debug
		printf("....W\n");
		CvMat_printdb(stdout,"%7.3f ",W);
*/
		lambda_max = W->data.db[0];
		lambda_min = W->data.db[((W->rows * W->cols) - 1)];
		RCondVal   = lambda_min / lambda_max;

		if(1 - (cvNorm(e, 0, CV_L2, 0) / cvNorm(eprev, 0, CV_L2, 0)) < 1000 * EPS)
		{
			cvReleaseMat(&J);
			cvReleaseMat(&e);
			cvReleaseMat(&J_tr);
			cvReleaseMat(&JtJ);
			cvReleaseMat(&W);
			break;
		}
		if(RCondVal < 10 * EPS)
		{
			cvReleaseMat(&J);
			cvReleaseMat(&e);
			cvReleaseMat(&J_tr);
			cvReleaseMat(&JtJ);
			cvReleaseMat(&W);
			break;
		}

		
		cvReleaseMat(&eprev);
		eprev = cvCreateMat(e->rows, e->cols, CV_64FC1); 
		cvCopy(e, eprev);

		Je = cvCreateMat(J->cols, e->cols, CV_64FC1);
		cvMatMul(J_tr, e, Je); /* (J'*e) */

		/*
		//debug
		printf("....J_tr\n");
		CvMat_printdb(stdout,"%7.3f ",J_tr);

		//debug
		printf("....e\n");
		CvMat_printdb(stdout,"%7.3f ",e);

		//debug
		printf("....JtJ\n");
		CvMat_printdb(stdout,"%7.3f ",JtJ);
		//debug
		printf("....Je\n");
		CvMat_printdb(stdout,"%7.3f ",Je);

		
		//debug
		printf("....JtJ\n");
		CvMat_printdb(stdout,"%7.3f ",JtJ);
*/
		cvInvert(JtJ,JtJ);
		/* (J'*J)\(J'*e) */
		Je=sfmMatMul(JtJ, Je);
/*
		//debug
		printf("....Je\n");
		CvMat_printdb(stdout,"%7.3f ",Je);
*/
		/* Y = Y - (J'*J)\(J'*e) */
		cvSub(Y, Je, Y, 0);
		/*
		//debug
		printf("....Y\n");
		CvMat_printdb(stdout,"%7.3f ",Y);
		*/
		cvReleaseMat(&J);
		cvReleaseMat(&e);
		cvReleaseMat(&J_tr);
		cvReleaseMat(&JtJ);
		cvReleaseMat(&Je);
		cvReleaseMat(&W);

	}
	Y_new  = cvCreateMat(4, 1, CV_64FC1);
	PutMatV(Y,Y_new,0);
	Y_new->data.db[3]=1;


	/*
	//debug
	printf("....Y_new\n");
	CvMat_printdb(stdout,"%7.3f ",Y_new);
	printf("....T\n");
	CvMat_printdb(stdout,"%7.3f ",T);
*/

	/* Obtain the new X */
    cvMatMul(T, Y_new, X);


	cvReleaseMat(&H);
	cvReleaseMat(&u_2_rows);
	
	cvReleaseMat(&U);
	cvReleaseMat(&T);
	cvReleaseMat(&Y);


	cvReleaseMat(&Y_new);
	cvReleaseMat(&T_2_cols);
	cvReleaseMat(&T_rest_cols);

	for(kp=0;kp<K;kp++)
	{
		cvReleaseMat(&P[kp]);
	}
	cvReleaseMat(&u);
	cvReleaseMat(&imsize);
	cvReleaseMatGrp(Q,K);

	return X;
}
コード例 #13
0
ファイル: gbt.cpp プロジェクト: Rocky030/opencv
void CvGBTrees::change_values(CvDTree* tree, const int _k)
{
    CvDTreeNode** predictions = new pCvDTreeNode[get_len(subsample_train)];

    int* sample_data = sample_idx->data.i;
    int* subsample_data = subsample_train->data.i;
    int s_step = (sample_idx->cols > sample_idx->rows) ? 1
                 : sample_idx->step/CV_ELEM_SIZE(sample_idx->type);

    CvMat x;
    CvMat miss_x;

    for (int i=0; i<get_len(subsample_train); ++i)
    {
        int idx = *(sample_data + subsample_data[i]*s_step);
        if (data->tflag == CV_ROW_SAMPLE)
            cvGetRow( data->train_data, &x, idx);
        else
            cvGetCol( data->train_data, &x, idx);

        if (missing)
        {
            if (data->tflag == CV_ROW_SAMPLE)
                cvGetRow( missing, &miss_x, idx);
            else
                cvGetCol( missing, &miss_x, idx);

            predictions[i] = tree->predict(&x, &miss_x);
        }
        else
            predictions[i] = tree->predict(&x);
    }


    CvDTreeNode** leaves;
    int leaves_count = 0;
    leaves = GetLeaves( tree, leaves_count);

    for (int i=0; i<leaves_count; ++i)
    {
        int samples_in_leaf = 0;
        for (int j=0; j<get_len(subsample_train); ++j)
        {
            if (leaves[i] == predictions[j]) samples_in_leaf++;
        }

        if (!samples_in_leaf) // It should not be done anyways! but...
        {
            leaves[i]->value = 0.0;
            continue;
        }

        CvMat* leaf_idx = cvCreateMat(1, samples_in_leaf, CV_32S);
        int* leaf_idx_data = leaf_idx->data.i;

        for (int j=0; j<get_len(subsample_train); ++j)
        {
            int idx = *(sample_data + subsample_data[j]*s_step);
            if (leaves[i] == predictions[j])
                *leaf_idx_data++ = idx;
        }

        float value = find_optimal_value(leaf_idx);
        leaves[i]->value = value;

        leaf_idx_data = leaf_idx->data.i;

        int len = sum_response_tmp->cols;
        for (int j=0; j<get_len(leaf_idx); ++j)
        {
            int idx = leaf_idx_data[j];
            sum_response_tmp->data.fl[idx + _k*len] =
                                    sum_response->data.fl[idx + _k*len] +
                                    params.shrinkage * value;
        }
        leaf_idx_data = 0;
        cvReleaseMat(&leaf_idx);
    }

    // releasing the memory
    for (int i=0; i<get_len(subsample_train); ++i)
    {
        predictions[i] = 0;
    }
    delete[] predictions;

    for (int i=0; i<leaves_count; ++i)
    {
        leaves[i] = 0;
    }
    delete[] leaves;

}
コード例 #14
0
ファイル: gbt.cpp プロジェクト: Rocky030/opencv
bool
CvGBTrees::train( const CvMat* _train_data, int _tflag,
              const CvMat* _responses, const CvMat* _var_idx,
              const CvMat* _sample_idx, const CvMat* _var_type,
              const CvMat* _missing_mask,
              CvGBTreesParams _params, bool /*_update*/ ) //update is not supported
{
    CvMemStorage* storage = 0;

    params = _params;
    bool is_regression = problem_type();

    clear();
    /*
      n - count of samples
      m - count of variables
    */
    int n = _train_data->rows;
    int m = _train_data->cols;
    if (_tflag != CV_ROW_SAMPLE)
    {
        int tmp;
        CV_SWAP(n,m,tmp);
    }

    CvMat* new_responses = cvCreateMat( n, 1, CV_32F);
    cvZero(new_responses);

    data = new CvDTreeTrainData( _train_data, _tflag, new_responses, _var_idx,
        _sample_idx, _var_type, _missing_mask, _params, true, true );
    if (_missing_mask)
    {
        missing = cvCreateMat(_missing_mask->rows, _missing_mask->cols,
                              _missing_mask->type);
        cvCopy( _missing_mask, missing);
    }

    orig_response = cvCreateMat( 1, n, CV_32F );
    int step = (_responses->cols > _responses->rows) ? 1 : _responses->step / CV_ELEM_SIZE(_responses->type);
    switch (CV_MAT_TYPE(_responses->type))
    {
        case CV_32FC1:
        {
            for (int i=0; i<n; ++i)
                orig_response->data.fl[i] = _responses->data.fl[i*step];
        }; break;
        case CV_32SC1:
        {
            for (int i=0; i<n; ++i)
                orig_response->data.fl[i] = (float) _responses->data.i[i*step];
        }; break;
        default:
            CV_Error(CV_StsUnmatchedFormats, "Response should be a 32fC1 or 32sC1 vector.");
    }

    if (!is_regression)
    {
        class_count = 0;
        unsigned char * mask = new unsigned char[n];
        memset(mask, 0, n);
        // compute the count of different output classes
        for (int i=0; i<n; ++i)
            if (!mask[i])
            {
                class_count++;
                for (int j=i; j<n; ++j)
                    if (int(orig_response->data.fl[j]) == int(orig_response->data.fl[i]))
                        mask[j] = 1;
            }
        delete[] mask;

        class_labels = cvCreateMat(1, class_count, CV_32S);
        class_labels->data.i[0] = int(orig_response->data.fl[0]);
        int j = 1;
        for (int i=1; i<n; ++i)
        {
            int k = 0;
            while ((int(orig_response->data.fl[i]) - class_labels->data.i[k]) && (k<j))
                k++;
            if (k == j)
            {
                class_labels->data.i[k] = int(orig_response->data.fl[i]);
                j++;
            }
        }
    }

    // inside gbt learning proccess only regression decision trees are built
    data->is_classifier = false;

    // preproccessing sample indices
    if (_sample_idx)
    {
        int sample_idx_len = get_len(_sample_idx);

        switch (CV_MAT_TYPE(_sample_idx->type))
        {
            case CV_32SC1:
            {
                sample_idx = cvCreateMat( 1, sample_idx_len, CV_32S );
                for (int i=0; i<sample_idx_len; ++i)
                    sample_idx->data.i[i] = _sample_idx->data.i[i];
            } break;
            case CV_8S:
            case CV_8U:
            {
                int active_samples_count = 0;
                for (int i=0; i<sample_idx_len; ++i)
                    active_samples_count += int( _sample_idx->data.ptr[i] );
                sample_idx = cvCreateMat( 1, active_samples_count, CV_32S );
                active_samples_count = 0;
                for (int i=0; i<sample_idx_len; ++i)
                    if (int( _sample_idx->data.ptr[i] ))
                        sample_idx->data.i[active_samples_count++] = i;

            } break;
            default: CV_Error(CV_StsUnmatchedFormats, "_sample_idx should be a 32sC1, 8sC1 or 8uC1 vector.");
        }
        icvSortFloat(sample_idx->data.fl, sample_idx_len, 0);
    }
    else
    {
        sample_idx = cvCreateMat( 1, n, CV_32S );
        for (int i=0; i<n; ++i)
            sample_idx->data.i[i] = i;
    }

    sum_response = cvCreateMat(class_count, n, CV_32F);
    sum_response_tmp = cvCreateMat(class_count, n, CV_32F);
    cvZero(sum_response);

    delta = 0.0f;
    /*
      in the case of a regression problem the initial guess (the zero term
      in the sum) is set to the mean of all the training responses, that is
      the best constant model
    */
    if (is_regression) base_value = find_optimal_value(sample_idx);
    /*
      in the case of a classification problem the initial guess (the zero term
      in the sum) is set to zero for all the trees sequences
    */
    else base_value = 0.0f;
    /*
      current predicition on all training samples is set to be
      equal to the base_value
    */
    cvSet( sum_response, cvScalar(base_value) );

    weak = new pCvSeq[class_count];
    for (int i=0; i<class_count; ++i)
    {
        storage = cvCreateMemStorage();
        weak[i] = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvDTree*), storage );
        storage = 0;
    }

    // subsample params and data
    rng = &cv::theRNG();

    int samples_count = get_len(sample_idx);

    params.subsample_portion = params.subsample_portion <= FLT_EPSILON ||
        1 - params.subsample_portion <= FLT_EPSILON
        ? 1 : params.subsample_portion;
    int train_sample_count = cvFloor(params.subsample_portion * samples_count);
    if (train_sample_count == 0)
        train_sample_count = samples_count;
    int test_sample_count = samples_count - train_sample_count;
    int* idx_data = new int[samples_count];
    subsample_train = cvCreateMatHeader( 1, train_sample_count, CV_32SC1 );
    *subsample_train = cvMat( 1, train_sample_count, CV_32SC1, idx_data );
    if (test_sample_count)
    {
        subsample_test  = cvCreateMatHeader( 1, test_sample_count, CV_32SC1 );
        *subsample_test = cvMat( 1, test_sample_count, CV_32SC1,
                                 idx_data + train_sample_count );
    }

    // training procedure

    for ( int i=0; i < params.weak_count; ++i )
    {
        do_subsample();
        for ( int k=0; k < class_count; ++k )
        {
            find_gradient(k);
            CvDTree* tree = new CvDTree;
            tree->train( data, subsample_train );
            change_values(tree, k);

            if (subsample_test)
            {
                CvMat x;
                CvMat x_miss;
                int* sample_data = sample_idx->data.i;
                int* subsample_data = subsample_test->data.i;
                int s_step = (sample_idx->cols > sample_idx->rows) ? 1
                             : sample_idx->step/CV_ELEM_SIZE(sample_idx->type);
                for (int j=0; j<get_len(subsample_test); ++j)
                {
                    int idx = *(sample_data + subsample_data[j]*s_step);
                    float res = 0.0f;
                    if (_tflag == CV_ROW_SAMPLE)
                        cvGetRow( data->train_data, &x, idx);
                    else
                        cvGetCol( data->train_data, &x, idx);

                    if (missing)
                    {
                        if (_tflag == CV_ROW_SAMPLE)
                            cvGetRow( missing, &x_miss, idx);
                        else
                            cvGetCol( missing, &x_miss, idx);

                        res = (float)tree->predict(&x, &x_miss)->value;
                    }
                    else
                    {
                        res = (float)tree->predict(&x)->value;
                    }
                    sum_response_tmp->data.fl[idx + k*n] =
                                    sum_response->data.fl[idx + k*n] +
                                    params.shrinkage * res;
                }
            }

            cvSeqPush( weak[k], &tree );
            tree = 0;
        } // k=0..class_count
    CvMat* tmp;
    tmp = sum_response_tmp;
    sum_response_tmp = sum_response;
    sum_response = tmp;
    tmp = 0;
    } // i=0..params.weak_count

    delete[] idx_data;
    cvReleaseMat(&new_responses);
    data->free_train_data();

    return true;

} // CvGBTrees::train(...)