コード例 #1
0
ファイル: myvideo.cpp プロジェクト: AprilWong/video-wizard
IplImage* MyVideo::resizeImage(IplImage* p, int width, int height) {
    IplImage* temp = 0;
    IplImage* result = 0;
    int pwidth = p->width;
    int pheight = p->height;
    float rate = float(width) / height;
    float prate = float(pwidth) / pheight;
    float scale;
    int off_left = 0;
    int off_top = 0;
    if( rate > prate ) {
        scale = float(height) / pheight;
        off_left = int(width - scale * pwidth) / 2;
    }
    else {
        scale = float(width) / pwidth;
        off_top = int(height - scale * pheight) / 2;
    }
    temp = cvCreateImage(cvSize((int)(pwidth * scale),(int)(pheight * scale)), 8, 3);
    cvResize(p, temp, CV_INTER_LINEAR);
    printf("%d %d %d %d\n", pwidth, pheight, temp->width, temp->height);
    result = cvCreateImage(cvSize((int)(width),(int)(height)), 8, 3);
    cvCopyMakeBorder(temp, result, cvPoint(off_left,off_top), IPL_BORDER_CONSTANT);
    return result;
}
コード例 #2
0
void copyMakeBorder( const Mat& src, Mat& dst, int top, int bottom,
                     int left, int right, int borderType, const Scalar& value )
{
    dst.create( src.rows + top + bottom, src.cols + left + right, src.type() );
    CvMat _src = src, _dst = dst;
    cvCopyMakeBorder( &_src, &_dst, Point(left, top), borderType, value );
}
コード例 #3
0
ファイル: roi.c プロジェクト: Farranco/HyperopicBarcode
void find_center_line(IplImage *blocks, int zoom,
					  CvPoint *best_left, CvPoint *best_right,
					  IplImage *debug)
{
	int longer =
		blocks->width > blocks->height ? blocks->width : blocks->height;
	CvSize border_size = cvSize(2 * longer, 2 * longer);
	IplImage *blocks_border = cvCreateImage(border_size, IPL_DEPTH_8U, 3);
	CvPoint offset = cvPoint((blocks_border->width - blocks->width) / 2,
							 (blocks_border->height - blocks->height) / 2);
	cvCopyMakeBorder(blocks, blocks_border, offset, IPL_BORDER_CONSTANT,
					 cvScalarAll(0));
	CvPoint left;
	CvPoint right;
	int quality;
	int best_quality = 0;
	int best_dir16 = 0;
	for (int dir16 = 0; dir16 < 8; dir16++) {
		find_box(blocks_border, offset, zoom, dir16, &left, &right,
				 &quality, debug);
		if (quality > best_quality) {
			best_quality = quality;
			best_dir16 = dir16;
			if (left.x <= right.x) {
				*best_left = left;
				*best_right = right;
			} else {
				*best_left = right;
				*best_right = left;
			}
		}
	}
	cvReleaseImage(&blocks_border);
	if (debug)
		cvLine(debug, *best_left, *best_right, cvScalar(255, 0, 0, 255), 3,
			   8, 0);
}
コード例 #4
0
ファイル: savgol.cpp プロジェクト: xufango/contrib_bk
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CvMat *savgolFilter(CvMat &z, double ra, double rb, double theta){

	int d=2;
	int k=1; // Always these, according to the matlab code (Leo)
	ra = max(1.5,ra);
	rb = max(1.5,rb);
	double ira2 = 1.0/(ra*ra);
	double irb2 = 1.0/(rb*rb);
	double wr = floor(max(ra,rb));
	double wd = 2*wr+1;
	double sint = sin(theta);
	double cost = cos(theta);

	CvMat*xx= cvCreateMat(2*d+1, 1, CV_64FC1);
	cvSetZero(xx);
	CvMat *temp=cvCreateMat(2*d+1, 1, CV_64FC1);

	for (int u=-wr;u<=wr;u++)
		for (int v=-wr;v<=wr;v++) {
			double ai=-u*sint+v*cost; //distance along major axis
			double bi= u*cost+v*sint; //distance along minor axis

			if (ai*ai*ira2+bi*bi*irb2 <= 1) {
				cvSet(temp, cvScalar(ai));
				cvSetReal2D(temp, 0, 0, 1.0);

				double dTemp=1;

				for (int i=0;i<2*d+1-1;i++) {
					dTemp=dTemp*cvGetReal2D(temp,i+1,0);
					cvSetReal2D(temp,i+1,0,dTemp);
				}

				cvAdd(xx,temp,xx);

			}
		}

		cvReleaseMat(&temp);

		CvMat *A=cvCreateMat(d+1,d+1,CV_64FC1);
		for (int i=0;i<d+1;i++)
			for (int j=i;j<=i+d;j++)
				cvSetReal2D(A,j-i,i,cvGetReal2D(xx,j,0));

		cvInvert(A,A,CV_LU);

		CvMat *zz=cvCreateMat(wd,wd, CV_64FC1);
		CvMat *yy=cvCreateMat(d+1,1, CV_64FC1);
		CvMat *result=cvCreateMat(d+1,1, CV_64FC1);
		CvMat *filt=cvCreateMat(wd,wd, CV_32FC1);
		cvSetZero(filt);


		for (int u=-wr;u<=wr;u++)
			for (int v=-wr;v<=wr;v++) {

				cvSetZero(zz);
				cvSetReal2D(zz,v+wr,u+wr,1);
				cvSetZero(yy);

				double ai=-u*sint+v*cost; //distance along major axis
				double bi= u*cost+v*sint; //distance along minor axis

				if (ai*ai*ira2+bi*bi*irb2 <= 1) {
					cvSet(yy, cvScalar(ai));
					cvSetReal2D(yy, 0, 0, 1.0);

					double dTemp=1;
					for (int i=0;i<d+1-1;i++) {
						dTemp=dTemp*cvGetReal2D(yy,i+1,0);
						cvSetReal2D(yy,i+1,0,dTemp);
					}

					cvMatMul(A,yy,result);
					cvSetReal2D(filt,v+wr,u+wr,cvGetReal2D(result,k-1,0));
				}
			}

			cvReleaseMat(&zz);
			cvReleaseMat(&yy);
			cvReleaseMat(&xx);
			cvReleaseMat(&A);

			CvMat *ztemp= cvCreateMat(z.rows+filt->rows-1,z.cols+filt->cols-1,CV_32FC1);
			cvCopyMakeBorder(&z,ztemp,cvPoint((filt->cols-1)/2,(filt->rows-1)/2),IPL_BORDER_CONSTANT);
			CvMat *filteredtemp= cvCreateMat(ztemp->rows,ztemp->cols,CV_32FC1);

			cvFilter2D(ztemp,filteredtemp,filt,cvPoint((filt->cols-1)/2,(filt->rows-1)/2));

			CvMat *filtered = cvCreateMat(z.rows,z.cols,CV_32FC1);
			cvGetSubRect(filteredtemp,filtered,cvRect((filt->cols-1)/2,(filt->rows-1)/2,z.cols,z.rows));

			return filtered;
}
コード例 #5
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;

}
コード例 #6
0
void
icvCrossCorr( const CvArr* _img, const CvArr* _templ, CvArr* _corr,
              CvPoint anchor, double delta, int borderType )
{
    // disable OpenMP in the case of Visual Studio,
    // otherwise the performance drops significantly
#undef USE_OPENMP
#if !defined _MSC_VER || defined CV_ICC
    #define USE_OPENMP 1
#endif

    const double block_scale = 4.5;
    const int min_block_size = 256;
    cv::Ptr<CvMat> dft_img[CV_MAX_THREADS];
    cv::Ptr<CvMat> dft_templ;
    std::vector<uchar> buf[CV_MAX_THREADS];
    int k, num_threads = 0;
    
    CvMat istub, *img = (CvMat*)_img;
    CvMat tstub, *templ = (CvMat*)_templ;
    CvMat cstub, *corr = (CvMat*)_corr;
    CvSize dftsize, blocksize;
    int depth, templ_depth, corr_depth, max_depth = CV_32F,
        cn, templ_cn, corr_cn, buf_size = 0,
        tile_count_x, tile_count_y, tile_count;

    img = cvGetMat( img, &istub );
    templ = cvGetMat( templ, &tstub );
    corr = cvGetMat( corr, &cstub );

    if( CV_MAT_DEPTH( img->type ) != CV_8U &&
        CV_MAT_DEPTH( img->type ) != CV_16U &&
        CV_MAT_DEPTH( img->type ) != CV_32F &&
        CV_MAT_DEPTH( img->type ) != CV_64F )
        CV_Error( CV_StsUnsupportedFormat,
        "The function supports only 8u, 16u and 32f data types" );

    if( !CV_ARE_DEPTHS_EQ( img, templ ) && CV_MAT_DEPTH( templ->type ) != CV_32F )
        CV_Error( CV_StsUnsupportedFormat,
        "Template (kernel) must be of the same depth as the input image, or be 32f" );
    
    if( !CV_ARE_DEPTHS_EQ( img, corr ) && CV_MAT_DEPTH( corr->type ) != CV_32F &&
        CV_MAT_DEPTH( corr->type ) != CV_64F )
        CV_Error( CV_StsUnsupportedFormat,
        "The output image must have the same depth as the input image, or be 32f/64f" );

    if( (!CV_ARE_CNS_EQ( img, corr ) || CV_MAT_CN(templ->type) > 1) &&
        (CV_MAT_CN( corr->type ) > 1 || !CV_ARE_CNS_EQ( img, templ)) )
        CV_Error( CV_StsUnsupportedFormat,
        "The output must have the same number of channels as the input (when the template has 1 channel), "
        "or the output must have 1 channel when the input and the template have the same number of channels" );

    depth = CV_MAT_DEPTH(img->type);
    cn = CV_MAT_CN(img->type);
    templ_depth = CV_MAT_DEPTH(templ->type);
    templ_cn = CV_MAT_CN(templ->type);
    corr_depth = CV_MAT_DEPTH(corr->type);
    corr_cn = CV_MAT_CN(corr->type);

    CV_Assert( corr_cn == 1 || delta == 0 );

    max_depth = MAX( max_depth, templ_depth );
    max_depth = MAX( max_depth, depth );
    max_depth = MAX( max_depth, corr_depth );
    if( depth > CV_8U )
        max_depth = CV_64F;

    /*if( img->cols < templ->cols || img->rows < templ->rows )
        CV_Error( CV_StsUnmatchedSizes,
        "Such a combination of image and template/filter size is not supported" );*/

    if( corr->rows > img->rows + templ->rows - 1 ||
        corr->cols > img->cols + templ->cols - 1 )
        CV_Error( CV_StsUnmatchedSizes,
        "output image should not be greater than (W + w - 1)x(H + h - 1)" );

    blocksize.width = cvRound(templ->cols*block_scale);
    blocksize.width = MAX( blocksize.width, min_block_size - templ->cols + 1 );
    blocksize.width = MIN( blocksize.width, corr->cols );
    blocksize.height = cvRound(templ->rows*block_scale);
    blocksize.height = MAX( blocksize.height, min_block_size - templ->rows + 1 );
    blocksize.height = MIN( blocksize.height, corr->rows );

    dftsize.width = cvGetOptimalDFTSize(blocksize.width + templ->cols - 1);
    if( dftsize.width == 1 )
        dftsize.width = 2;
    dftsize.height = cvGetOptimalDFTSize(blocksize.height + templ->rows - 1);
    if( dftsize.width <= 0 || dftsize.height <= 0 )
        CV_Error( CV_StsOutOfRange, "the input arrays are too big" );

    // recompute block size
    blocksize.width = dftsize.width - templ->cols + 1;
    blocksize.width = MIN( blocksize.width, corr->cols );
    blocksize.height = dftsize.height - templ->rows + 1;
    blocksize.height = MIN( blocksize.height, corr->rows );

    dft_templ = cvCreateMat( dftsize.height*templ_cn, dftsize.width, max_depth );

#ifdef USE_OPENMP
    num_threads = cvGetNumThreads();
#else
    num_threads = 1;
#endif

    for( k = 0; k < num_threads; k++ )
        dft_img[k] = cvCreateMat( dftsize.height, dftsize.width, max_depth );

    if( templ_cn > 1 && templ_depth != max_depth )
        buf_size = templ->cols*templ->rows*CV_ELEM_SIZE(templ_depth);

    if( cn > 1 && depth != max_depth )
        buf_size = MAX( buf_size, (blocksize.width + templ->cols - 1)*
            (blocksize.height + templ->rows - 1)*CV_ELEM_SIZE(depth));

    if( (corr_cn > 1 || cn > 1) && corr_depth != max_depth )
        buf_size = MAX( buf_size, blocksize.width*blocksize.height*CV_ELEM_SIZE(corr_depth));

    if( buf_size > 0 )
    {
        for( k = 0; k < num_threads; k++ )
            buf[k].resize(buf_size);
    }

    // compute DFT of each template plane
    for( k = 0; k < templ_cn; k++ )
    {
        CvMat dstub, *src, *dst, temp;
        CvMat* planes[] = { 0, 0, 0, 0 };
        int yofs = k*dftsize.height;

        src = templ;
        dst = cvGetSubRect( dft_templ, &dstub, cvRect(0,yofs,templ->cols,templ->rows));
    
        if( templ_cn > 1 )
        {
            planes[k] = templ_depth == max_depth ? dst :
                cvInitMatHeader( &temp, templ->rows, templ->cols, templ_depth, &buf[0][0] );
            cvSplit( templ, planes[0], planes[1], planes[2], planes[3] );
            src = planes[k];
            planes[k] = 0;
        }

        if( dst != src )
            cvConvert( src, dst );

        if( dft_templ->cols > templ->cols )
        {
            cvGetSubRect( dft_templ, dst, cvRect(templ->cols, yofs,
                          dft_templ->cols - templ->cols, templ->rows) );
            cvZero( dst );
        }
        cvGetSubRect( dft_templ, dst, cvRect(0,yofs,dftsize.width,dftsize.height) );
        cvDFT( dst, dst, CV_DXT_FORWARD + CV_DXT_SCALE, templ->rows );
    }

    tile_count_x = (corr->cols + blocksize.width - 1)/blocksize.width;
    tile_count_y = (corr->rows + blocksize.height - 1)/blocksize.height;
    tile_count = tile_count_x*tile_count_y;

#if defined _OPENMP && defined USE_OPENMP
    #pragma omp parallel for num_threads(num_threads) schedule(dynamic)
#endif
    // calculate correlation by blocks
    for( k = 0; k < tile_count; k++ )
    {
#ifdef USE_OPENMP
        int thread_idx = cvGetThreadNum();
#else
        int thread_idx = 0;
#endif
        int x = (k%tile_count_x)*blocksize.width;
        int y = (k/tile_count_x)*blocksize.height;
        int i, yofs;
        CvMat sstub, dstub, *src, *dst, temp;
        CvMat* planes[] = { 0, 0, 0, 0 };
        CvMat* _dft_img = dft_img[thread_idx];
        uchar* _buf = buf_size > 0 ? &buf[thread_idx][0] : 0;
        CvSize csz = { blocksize.width, blocksize.height }, isz;
        int x0 = x - anchor.x, y0 = y - anchor.y;
        int x1 = MAX( 0, x0 ), y1 = MAX( 0, y0 ), x2, y2;
        csz.width = MIN( csz.width, corr->cols - x );
        csz.height = MIN( csz.height, corr->rows - y );
        isz.width = csz.width + templ->cols - 1;
        isz.height = csz.height + templ->rows - 1;
        x2 = MIN( img->cols, x0 + isz.width );
        y2 = MIN( img->rows, y0 + isz.height );
        
        for( i = 0; i < cn; i++ )
        {
            CvMat dstub1, *dst1;
            yofs = i*dftsize.height;

            src = cvGetSubRect( img, &sstub, cvRect(x1,y1,x2-x1,y2-y1) );
            dst = cvGetSubRect( _dft_img, &dstub,
                cvRect(0,0,isz.width,isz.height) );
            dst1 = dst;
            
            if( x2 - x1 < isz.width || y2 - y1 < isz.height )
                dst1 = cvGetSubRect( _dft_img, &dstub1,
                    cvRect( x1 - x0, y1 - y0, x2 - x1, y2 - y1 ));

            if( cn > 1 )
            {
                planes[i] = dst1;
                if( depth != max_depth )
                    planes[i] = cvInitMatHeader( &temp, y2 - y1, x2 - x1, depth, _buf );
                cvSplit( src, planes[0], planes[1], planes[2], planes[3] );
                src = planes[i];
                planes[i] = 0;
            }

            if( dst1 != src )
                cvConvert( src, dst1 );

            if( dst != dst1 )
                cvCopyMakeBorder( dst1, dst, cvPoint(x1 - x0, y1 - y0), borderType );

            if( dftsize.width > isz.width )
            {
                cvGetSubRect( _dft_img, dst, cvRect(isz.width, 0,
                      dftsize.width - isz.width,dftsize.height) );
                cvZero( dst );
            }

            cvDFT( _dft_img, _dft_img, CV_DXT_FORWARD, isz.height );
            cvGetSubRect( dft_templ, dst,
                cvRect(0,(templ_cn>1?yofs:0),dftsize.width,dftsize.height) );

            cvMulSpectrums( _dft_img, dst, _dft_img, CV_DXT_MUL_CONJ );
            cvDFT( _dft_img, _dft_img, CV_DXT_INVERSE, csz.height );

            src = cvGetSubRect( _dft_img, &sstub, cvRect(0,0,csz.width,csz.height) );
            dst = cvGetSubRect( corr, &dstub, cvRect(x,y,csz.width,csz.height) );

            if( corr_cn > 1 )
            {
                planes[i] = src;
                if( corr_depth != max_depth )
                {
                    planes[i] = cvInitMatHeader( &temp, csz.height, csz.width,
                                                 corr_depth, _buf );
                    cvConvertScale( src, planes[i], 1, delta );
                }
                cvMerge( planes[0], planes[1], planes[2], planes[3], dst );
                planes[i] = 0;                    
            }
            else
            {
                if( i == 0 )
                    cvConvertScale( src, dst, 1, delta );
                else
                {
                    if( max_depth > corr_depth )
                    {
                        cvInitMatHeader( &temp, csz.height, csz.width,
                                         corr_depth, _buf );
                        cvConvert( src, &temp );
                        src = &temp;
                    }
                    cvAcc( src, dst );
                }
            }
        }
    }
}
コード例 #7
0
int main(int argc, char* argv[])
{
	const char* name = "Edge Detection Window";

	// Kernel size
	int N = 7;

	// Set up original image
	IplImage* org_img = cvLoadImage( argv[1], 0 );
	
	// resize original image
	IplImage* img = cvCreateImage(cvSize(512,512),org_img->depth, org_img->nChannels);
	cvResize(org_img, img);

	// created final image
	IplImage* img_b = cvCreateImage( cvSize(img->width+N-1,img->height+N-1), img->depth, img->nChannels );
	IplImage* out = cvCreateImage( cvGetSize(img_b), IPL_DEPTH_8U, img_b->nChannels );

	// Add convolution boarders
	CvPoint offset = cvPoint((N-1)/2,(N-1)/2);
	cvCopyMakeBorder(img, img_b, offset, IPL_BORDER_REPLICATE, cvScalarAll(0));

	// Make window
	cvNamedWindow( name, 1 );
	
	// Edge Detection Variables
	int aperature_size = N;
	double lowThresh = 20;
	double highThresh = 40;

	// Create trackbars
	cvCreateTrackbar( "High", name, &high_switch_value, 4, switch_callback_h );
	cvCreateTrackbar( "Low", name, &low_switch_value, 4, switch_callback_l );

	while( 1 ) {
		switch( highInt ){
			case 0:
				highThresh = 200;
				break;
			case 1:
				highThresh = 400;
				break;
			case 2:
				highThresh = 600;
				break;
			case 3:
				highThresh = 800;
				break;
			case 4:
				highThresh = 1000;
				break;
		}
		switch( lowInt ){
			case 0:
				lowThresh = 0;
				break;
			case 1:
				lowThresh = 100;
				break;
			case 2:
				lowThresh = 200;
				break;
			case 3:
				lowThresh = 400;
				break;
			case 4:
				lowThresh = 600;
				break;
		}

		// Edge Detection
		cvCanny( img_b, out, lowThresh*N*N, highThresh*N*N, aperature_size );		
		cvShowImage(name, out);
		
		if( cvWaitKey( 15 ) == 27 ) 
			break;
	}

	// Release
	cvReleaseImage( &img );
	cvReleaseImage( &img_b );
	cvReleaseImage( &out );
	cvDestroyWindow( name );

	return 0;
}
コード例 #8
0
bool EyeCoord2FaceCrop( IplImage * pic8, CvMat * faceImg8,  CvPoint2D32f leftEye, 
					   CvPoint2D32f rightEye, bool useBuf )
{
	static int idx = 0;
	static bool bInited = false;
	CvPoint2D32f l1 = cvPoint2D32f(0,0), r1 = cvPoint2D32f(0,0);
	if (useBuf) // when detect face in a video stream, one may hope the position changes more smoothly. So we smooth the eye coordinates between each call
	{
		g_lefta[idx] = leftEye;
		g_righta[idx++] = rightEye;
		idx %= g_nFiltLevel;

		if (!bInited)
		{
			for (int i = 1; i < g_nFiltLevel; i++)
			{
				g_lefta[i] = leftEye;
				g_righta[i] = rightEye;
			}
		}

		for (int i = 0; i < g_nFiltLevel; i++) // smooth the coordinates
		{
			l1.x += g_lefta[i].x/g_nFiltLevel;
			l1.y += g_lefta[i].y/g_nFiltLevel;
			r1.x += g_righta[i].x/g_nFiltLevel;
			r1.y += g_righta[i].y/g_nFiltLevel;
		}
	}
	else
	{
		l1 = leftEye;
		r1 = rightEye;
	}

	float xDis = r1.x - l1.x,
		yDis = r1.y - l1.y;

	g_angle = cvFastArctan(yDis, xDis);
	g_dis = sqrt(xDis*xDis + yDis*yDis);


	CvMat *map = cvCreateMat(2, 3, CV_32FC1);
	CvMat *largePic8 = cvCreateMat(pic8->height*2, pic8->width*2, CV_8UC1); // in case the cropped face goes out of the border
	CvMat *tmpDst = cvCreateMat(largePic8->height, largePic8->width, CV_8UC1);
	cvCopyMakeBorder(pic8, largePic8, cvPoint(pic8->width/2, pic8->height/2), IPL_BORDER_REPLICATE);

	l1.x += pic8->width/2;
	l1.y += pic8->height/2;
	cv2DRotationMatrix(l1, g_angle, g_normDis/g_dis, map); // similar transformation
	//DispCvArr(map, "map");
	cvWarpAffine(largePic8, tmpDst, map);
	//cvShowImage("a",tmpDst);
	//cvWaitKey();

	int		leftEyeXNew = cvRound((g_faceSz.width - g_normDis)/2);
	int		left = cvRound(l1.x - leftEyeXNew),
		top = cvRound(l1.y - g_normRow);
	CvMat	tmpHeader, *sub = 0;

	if (left >= 0 && top >= 0 &&
		left + g_faceSz.width <= tmpDst->width &&
		top + g_faceSz.height <= tmpDst->height)
	{	
		sub = cvGetSubRect(tmpDst, &tmpHeader, cvRect(left, top, g_faceSz.width, g_faceSz.height));
		cvCopy(sub, faceImg8);
		//cvShowImage("f",faceImg8);
		//cvWaitKey();
	}

	cvReleaseMat(&map);
	cvReleaseMat(&largePic8);
	cvReleaseMat(&tmpDst);
	return (sub != 0);
}
コード例 #9
0
ファイル: main.c プロジェクト: freeboy1015/deblur
int main( int argc, char* argv[]){

    char c;
    int fileFlag = 0, psfFlag = 0, errFlag = 0, gpuFlag = 0, kernelSize = 2, blurFlag = 0,
        ux = 0, uy = 0;
    float stddev = 1.0f;
    double snr = 0.005;
    char *filename, *psfname;
    extern char *optarg;
    extern int optind, optopt, opterr;

    while ((c = getopt(argc, argv, ":bgk:s:d:f:p:x:y:")) != -1) {
        switch(c) {
            case 'b':
                printf("Blur image first\n");
                blurFlag = 1;
                break;
            case 'g':
                printf("Use GPU Kernel\n");
                gpuFlag = 1;
                break;
            case 'k':
                kernelSize = atoi(optarg);
                printf("Kernel size: %d\n", kernelSize);
                break;
            case 's':
                snr = atof(optarg);
                printf("Singal-to-noise ratio: %f\n", snr);
                break;
            case 'd':
                stddev = atof(optarg);
                printf("Kernel stddev: %f\n", stddev);
                break;
            case 'f':
                filename = optarg;
                fileFlag = 1;
                printf("Processing file: %s\n", filename);
                break;
            case 'p':
                psfname = optarg;
                psfFlag = 1;
                printf("Kernel image: %s\n", psfname);
                break;
            case 'x':
                ux = atoi(optarg);
                printf("Offset X: %d\n", ux);
                break;
            case 'y':
                uy = atoi(optarg);
                printf("Offset Y: %d\n", uy);
                break;
            case ':':
                printf("-%c without input\n", optopt);
                errFlag++;
                break;
            case '?':
                printf("unknown arg %c\n", optopt);
                errFlag++;
                break;
        }
    }

    if (errFlag || !fileFlag) {
        goto ERROR;
    }

    IplImage* img;
    IplImage* srcImg = cvLoadImage(filename, CV_LOAD_IMAGE_COLOR);

    if (!srcImg) 
        goto ERROR;

    int side = max(srcImg->width, srcImg->height) + kernelSize * 2;

    if (srcImg->height != srcImg->width) {
        CvSize size = cvSize(side, side);
        img = cvCreateImage(size, IPL_DEPTH_8U, 3);
        CvPoint offset = cvPoint((side - srcImg->width) / 2, (side - srcImg->height) / 2);
        cvCopyMakeBorder(srcImg, img, offset, IPL_BORDER_REPLICATE, cvScalarAll(0));
    } else {
        img = srcImg;
    }

    IplImage* imgSplit[3];
    for(int c = 0; c < 3; ++c)
        imgSplit[c] = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    cvSplit(img, imgSplit[0], imgSplit[1], imgSplit[2], NULL);

    printf("Height: %d, Width: %d\n", img->height, img->width);

    double * psf = (double *) malloc (sizeof(double) * img->width * img->height);
    for (int i = 0; i < img->width * img->height; i++)
        psf[i] = 0.;

    if(!img || !psf) return 1;

    double scale = 0;

    // cyclic 
    if (psfFlag) {
        IplImage *kernelImage = cvLoadImage(psfname, CV_LOAD_IMAGE_GRAYSCALE);
        if (!kernelImage) {
            goto ERROR;
        }
        scale = readPSF(psf, kernelImage, img->height, img->width);
    } else {
        scale = genPSF(psf, img->height, img->width, kernelSize, stddev, ux, uy);
    }

    IplImage* psfImg = cvCreateImage(cvGetSize(img), IPL_DEPTH_64F, 1);

    for(int h = 0 ; h < img->height; ++h){
        for( int w = 0; w < img->width; ++w){
            IMG_ELEM_DOUBLE(psfImg, h, w) = psf[h * img->width + w];
        }
    }

    if (blurFlag) {
        imgSplit[0] = blurPSF(imgSplit[0], psfImg);
        imgSplit[1] = blurPSF(imgSplit[1], psfImg);
        imgSplit[2] = blurPSF(imgSplit[2], psfImg);
        cvMerge(imgSplit[0], imgSplit[1], imgSplit[2], NULL, img);
    }

    IplImage* dbl1;
    IplImage* dbl2;
    IplImage* dbl3;

    if (gpuFlag) {
        dbl1 = deblurGPU(imgSplit[0], psfImg, snr, scale);
        dbl2 = deblurGPU(imgSplit[1], psfImg, snr, scale);
        dbl3 = deblurGPU(imgSplit[2], psfImg, snr, scale);
    } else {
        dbl1 = deblurFilter(imgSplit[0], psfImg, snr, scale);
        dbl2 = deblurFilter(imgSplit[1], psfImg, snr, scale);
        dbl3 = deblurFilter(imgSplit[2], psfImg, snr, scale);
    }


    IplImage* dbl = cvClone(img);
    cvMerge(dbl1, dbl2, dbl3, NULL, dbl);

    char psfFile[256], blurFile[256], deblurFile[256];

    char *pch = strchr(filename, '.');
    (*pch) = '\0';

    if (blurFlag) {
        snprintf(psfFile, 250, "%s_psf.png", filename);
        snprintf(blurFile, 250, "%s_blur.png", filename);
    }

    if (psfFlag) {
        snprintf(deblurFile, 250, "%s_%2.4f_deblur.png", filename, snr);
    } else {
        snprintf(deblurFile, 250, "%s_%d_%2.2f_%2.4f_%d_%d_deblur.png", filename, kernelSize, stddev, snr, ux, uy);
    }

    // ROI
    IplImage* blurROI;
    IplImage* deblurROI;

    CvRect rect;

    rect.x = (side - srcImg->width) / 2; 
    rect.y = (side - srcImg->height) / 2; 
    rect.width = srcImg->width;
    rect.height = srcImg->height;

    if (blurFlag) {
        cvSetImageROI(img, rect);
        blurROI = cvCloneImage(img);

        cvSaveImage(psfFile, psfImg, 0);
        cvSaveImage(blurFile, blurROI, 0);
    }

    cvSetImageROI(dbl, rect);
    deblurROI = cvCloneImage(dbl);
    cvSaveImage(deblurFile, deblurROI, 0);

    cvReleaseImage(&imgSplit[0]);
    cvReleaseImage(&imgSplit[1]);
    cvReleaseImage(&imgSplit[2]);

    cvReleaseImage(&psfImg);
    cvReleaseImage(&img);

    cvReleaseImage(&dbl);
    cvReleaseImage(&dbl1);
    cvReleaseImage(&dbl2);
    cvReleaseImage(&dbl3);

    return 0;

ERROR:
    fprintf(stderr, "Usage: -f [/path/to/image]                path to the image file\n"); 
    fprintf(stderr, "       -p [/path/to/kernel]               path to the kernel\n"); 
    fprintf(stderr, "       -k [2]                             kernel size\n"); 
    fprintf(stderr, "       -s [0.005]                         signal-to-noise ratio\n"); 
    fprintf(stderr, "       -d [1.0]                           standard deviation\n"); 
    fprintf(stderr, "       -x [0]                             center offset x\n"); 
    fprintf(stderr, "       -y [0]                             center offset y\n"); 
    fprintf(stderr, "       -g                                 use GPU kernel\n"); 
    fprintf(stderr, "       -b                                 blur image first\n"); 
    return 1;

}
コード例 #10
0
ファイル: fts_anpr_seg.cpp プロジェクト: matthill/DemoOpenCV
void FTS_ANPR_Seg::extractCharByCCAnalysis( const cv::Mat& oBin,
                                            FTS_ANPR_SegResult& oSegResult )
{
    // Padd the input image first
    // ------------------------------------------------------------------------
	m_oPadded.create( oBin.rows + 2,
					  oBin.cols  + 2,
					  CV_8UC1 );
	cv::copyMakeBorder( oBin, m_oPadded, 1, 1, 1, 1, cv::BORDER_CONSTANT );

    IplImage iiBin    = oBin;
    IplImage iiPadded = m_oPadded;

    cvCopyMakeBorder( &iiBin,
                      &iiPadded,
                      cvPoint( 1, 1 ),
                      IPL_BORDER_CONSTANT,
                      cvScalarAll( 0 )  ); // pad with black border


    // Initializes contour scanning process
    // ------------------------------------------------------------------------
    CvSeq* poContour = 0;
    CvContourScanner oContourScanner;

    oContourScanner = cvStartFindContours( &iiPadded,
                                           m_poStorage,
                                           sizeof( CvContour ),
                                           CV_RETR_EXTERNAL, //CV_RETR_LIST,
                                           CV_CHAIN_APPROX_SIMPLE,
                                           cvPoint( 0, 0 )  );

    // Contour scanning process
    // ------------------------------------------------------------------------
    while(  ( poContour = cvFindNextContour( oContourScanner ) )  )
    {
        // Finding bounding boxes that meet the ratio tests
        // --------------------------------------------------------------------
        CvRect oBox = cvBoundingRect( poContour, 0 );

        if(    !testArea( oBox )
            || !testHeightOverWidth( oBox )
            || !testHeight( oBox.height, iiBin.height )  )
        {
            continue;
        }

        std::list< FTS_ANPR_SegChar*>& oChars = oSegResult.m_oChars;

        // Make sure not too many candidates
        // --------------------------------------------------------------------
        if( oChars.size() >= m_nMaxNumCharCandidates )
        {
            break; // exit the while loop
        }

        // Store the character candidate to the segmentation structure
        // --------------------------------------------------------------------
        oChars.push_back( new FTS_ANPR_SegChar );

        FTS_ANPR_SegChar& oSegChar = *( oChars.back() ); // fill in the empty object

        oSegChar.m_oCharRect = oBox;

        // Offset the bounding box from coordinates in padded image, into coordinates of input image.
        --oSegChar.m_oCharRect.x;
        --oSegChar.m_oCharRect.y;

//        oSegChar.m_oCharBin.resize(oBox.width, oBox.height, SN_PIX_FMT_GREY );
        oSegChar.m_oCharBin = cv::Mat::zeros( cv::Size( oSegChar.m_oCharRect.width, oSegChar.m_oCharRect.height ), CV_8UC1 );

        IplImage iiSegCharBin = oSegChar.m_oCharBin;
//        cvZero( &iiSegCharBin );
//        printf("width = %d, height = %d\n", oSegChar.m_oCharRect.width, oSegChar.m_oCharRect.height );

        // Draw the outer contour and fill all holes. No internal holes
        // after this.
        cvDrawContours( &iiSegCharBin,
                        poContour,
                        CV_RGB( 255, 255, 255 ),
                        CV_RGB( 255, 255, 255 ),
                        1,
                        CV_FILLED,
                        8,
                        cvPoint( -oBox.x, -oBox.y ) // offset contour to smaller image
                        );

        // Recover all the holes in the original image
        cvSetImageROI( &iiBin, oSegChar.m_oCharRect );
        cvAnd( &iiBin, &iiSegCharBin, &iiSegCharBin, 0 );

//        cv::namedWindow( "CCCCCCCCCCCCCCCCCCCCCCC" );
//        cv::imshow( "CCCCCCCCCCCCCCCCCCCCCCC", oSegChar.m_oCharBin );
//        cv::waitKey();
    }

    cvResetImageROI( &iiBin );
    cvEndFindContours( &oContourScanner );


    // Sort the segments using x-coordinate
    // --------------------------------------------------------------------
    oSegResult.m_oChars.sort( &FTS_ANPR_SegChar::LessInX );
}
コード例 #11
0
ファイル: cl-opencv-glue.c プロジェクト: 3b/cl-opencv
void cvCopyMakeBorder_glue(const CvArr* src, CvArr* dst, CvPoint offset, 
			   int bordertype, CV_SCALAR_DECL(value))
{
    cvCopyMakeBorder(src, dst, offset, bordertype, CV_SCALAR(value));
}
コード例 #12
0
ファイル: distransform.cpp プロジェクト: 2693/opencv
/* Wrapper function for distance transform group */
CV_IMPL void
cvDistTransform( const void* srcarr, void* dstarr,
                 int distType, int maskSize,
                 const float *mask,
                 void* labelsarr, int labelType )
{
    float _mask[5] = {0};
    CvMat srcstub, *src = (CvMat*)srcarr;
    CvMat dststub, *dst = (CvMat*)dstarr;
    CvMat lstub, *labels = (CvMat*)labelsarr;

    src = cvGetMat( src, &srcstub );
    dst = cvGetMat( dst, &dststub );

    if( !CV_IS_MASK_ARR( src ) || (CV_MAT_TYPE( dst->type ) != CV_32FC1 &&
        (CV_MAT_TYPE(dst->type) != CV_8UC1 || distType != CV_DIST_L1 || labels)) )
        CV_Error( CV_StsUnsupportedFormat,
        "source image must be 8uC1 and the distance map must be 32fC1 "
        "(or 8uC1 in case of simple L1 distance transform)" );

    if( !CV_ARE_SIZES_EQ( src, dst ))
        CV_Error( CV_StsUnmatchedSizes, "the source and the destination images must be of the same size" );

    if( maskSize != CV_DIST_MASK_3 && maskSize != CV_DIST_MASK_5 && maskSize != CV_DIST_MASK_PRECISE )
        CV_Error( CV_StsBadSize, "Mask size should be 3 or 5 or 0 (presize)" );

    if( distType == CV_DIST_C || distType == CV_DIST_L1 )
        maskSize = !labels ? CV_DIST_MASK_3 : CV_DIST_MASK_5;
    else if( distType == CV_DIST_L2 && labels )
        maskSize = CV_DIST_MASK_5;

    if( maskSize == CV_DIST_MASK_PRECISE )
    {
        icvTrueDistTrans( src, dst );
        return;
    }

    if( labels )
    {
        labels = cvGetMat( labels, &lstub );
        if( CV_MAT_TYPE( labels->type ) != CV_32SC1 )
            CV_Error( CV_StsUnsupportedFormat, "the output array of labels must be 32sC1" );

        if( !CV_ARE_SIZES_EQ( labels, dst ))
            CV_Error( CV_StsUnmatchedSizes, "the array of labels has a different size" );

        if( maskSize == CV_DIST_MASK_3 )
            CV_Error( CV_StsNotImplemented,
            "3x3 mask can not be used for \"labeled\" distance transform. Use 5x5 mask" );
    }

    if( distType == CV_DIST_C || distType == CV_DIST_L1 || distType == CV_DIST_L2 )
    {
        icvGetDistanceTransformMask( (distType == CV_DIST_C ? 0 :
            distType == CV_DIST_L1 ? 1 : 2) + maskSize*10, _mask );
    }
    else if( distType == CV_DIST_USER )
    {
        if( !mask )
            CV_Error( CV_StsNullPtr, "" );

        memcpy( _mask, mask, (maskSize/2 + 1)*sizeof(float));
    }

    CvSize size = cvGetMatSize(src);

    if( CV_MAT_TYPE(dst->type) == CV_8UC1 )
    {
        icvDistanceATS_L1_8u( src, dst );
    }
    else
    {
        int border = maskSize == CV_DIST_MASK_3 ? 1 : 2;
        cv::Ptr<CvMat> temp = cvCreateMat( size.height + border*2, size.width + border*2, CV_32SC1 );

        if( !labels )
        {
            CvDistTransFunc func = maskSize == CV_DIST_MASK_3 ?
                icvDistanceTransform_3x3_C1R :
                icvDistanceTransform_5x5_C1R;

            func( src->data.ptr, src->step, temp->data.i, temp->step,
                  dst->data.fl, dst->step, size, _mask );
        }
        else
        {
            cvZero( labels );

            if( labelType == CV_DIST_LABEL_CCOMP )
            {
                CvSeq *contours = 0;
                cv::Ptr<CvMemStorage> st = cvCreateMemStorage();
                cv::Ptr<CvMat> src_copy = cvCreateMat( size.height+border*2, size.width+border*2, src->type );
                cvCopyMakeBorder(src, src_copy, cvPoint(border, border), IPL_BORDER_CONSTANT, cvScalarAll(255));
                cvCmpS( src_copy, 0, src_copy, CV_CMP_EQ );
                cvFindContours( src_copy, st, &contours, sizeof(CvContour),
                               CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(-border, -border));

                for( int label = 1; contours != 0; contours = contours->h_next, label++ )
                {
                    CvScalar area_color = cvScalarAll(label);
                    cvDrawContours( labels, contours, area_color, area_color, -255, -1, 8 );
                }
            }
            else
            {
                int k = 1;
                for( int i = 0; i < src->rows; i++ )
                {
                    const uchar* srcptr = src->data.ptr + src->step*i;
                    int* labelptr = (int*)(labels->data.ptr + labels->step*i);

                    for( int j = 0; j < src->cols; j++ )
                        if( srcptr[j] == 0 )
                            labelptr[j] = k++;
                }
            }

            icvDistanceTransformEx_5x5_C1R( src->data.ptr, src->step, temp->data.i, temp->step,
                        dst->data.fl, dst->step, labels->data.i, labels->step, size, _mask );
        }
    }
}