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; }
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 ); }
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); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- 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; }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ 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; }
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 ); } } } } }
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; }
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); }
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; }
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 ); }
void cvCopyMakeBorder_glue(const CvArr* src, CvArr* dst, CvPoint offset, int bordertype, CV_SCALAR_DECL(value)) { cvCopyMakeBorder(src, dst, offset, bordertype, CV_SCALAR(value)); }
/* 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 ); } } }