void cvCLAdaptEqualize(const CvArr* srcarr, CvArr* dstarr, unsigned int xdivs, unsigned int ydivs, unsigned int bins, float limit, int range) { double min_val, max_val; unsigned char min, max; int type; IplImage sstub, *src = cvGetImage(srcarr, &sstub); IplImage dstub, *dst = cvGetImage(dstarr, &dstub); if ((src == NULL) || (dst == NULL)) CV_ERROR( CV_StsUnsupportedFormat, "NULL value passed as image to function" ); CV_CALL( type = cvGetElemType( src )); if( type != CV_8UC1 ) CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" ); CV_CALL( type = cvGetElemType( src )); if( type != CV_8UC1 ) CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" ); //if( !CV_ARE_SIZES_EQ( src, dst )) // Modified by Shervin Emami, 17Nov2010. if (src->width != dst->width || src->height != dst->height) CV_ERROR( CV_StsUnmatchedSizes, "src and dst images must be equal sizes" ); if (((xdivs < 2) || (xdivs > 16)) || ((ydivs < 2) || (ydivs > 16))) CV_ERROR( CV_StsBadFlag, "xdivs and ydivs must in range (MIN=2 MAX = 16)" ); if ((bins < 2) || (bins > 256)) CV_ERROR( CV_StsBadFlag, "bins must in range (MIN=2 MAX = 256)" ); // copy src to dst for in-place CLAHE. cvCopy(src, dst); // If the dimensions of the image are not a multiple of the xdivs and ydivs, then enlarge the image to be a correct size and then shrink the image. // Also make sure the image is aligned to 8 pixels width, so that OpenCV won't add extra padding to the image. // Added by Shervin Emami, 17Nov2010. int enlarged = 0; int origW = dst->width; int origH = dst->height; IplImage *tmpDst = 0; if ((dst->width & (8-1)) || (dst->height & (8-1)) || (dst->width % xdivs) || (dst->height % ydivs)) { int newW = ((dst->width + 8-1) & -8); // Align to 8 pixels, so that widthStep hopefully equals width. newW = ((newW + xdivs-1) & -xdivs); // Also align for CLAHE. int newH = ((dst->height + ydivs-1) & -ydivs); //std::cout << "w=" << dst->width << ", h=" << dst->height << ". new w = " << newW << ", h = " << newH << std::endl; IplImage *enlargedDst = cvCreateImage(cvSize(newW, newH), dst->depth, dst->nChannels); cvResize(dst, enlargedDst, CV_INTER_CUBIC); //cvReleaseImage(&dst); tmpDst = dst; dst = enlargedDst; // Use the enlarged image instead of the original dst image. enlarged = 1; // signal that we need to shrink later! } // Check if OpenCV adds padding bytes on each row. Added by Shervin Emami, 17Nov2010. if (dst->width != dst->widthStep) CV_ERROR( CV_StsBadFlag, "dst->widthStep should be the same as dst->width. The IplImage has padding, so use a larger image." ); // check number of xdivs and ydivs is a multiple of image dimensions if (dst->width % xdivs) CV_ERROR( CV_StsBadFlag, "xdiv must be an integer multiple of image width " ); if (dst->height % ydivs) CV_ERROR( CV_StsBadFlag, "ydiv must be an integer multiple of image height " ); // get the min and max values of the image if (range == CV_CLAHE_RANGE_INPUT) { cvMinMaxLoc(dst, &min_val, &max_val); min = (unsigned char) min_val; max = (unsigned char) max_val; } else { min = 0; max = 255; } // call CLHAHE for in-place CLAHE //int rcode = CLAHE((kz_pixel_t*) (dst->imageData), (unsigned int) dst->width, (unsigned int) dst->height, (kz_pixel_t) min, (kz_pixel_t) max, (unsigned int) xdivs, (unsigned int) ydivs, (unsigned int) bins, (float) limit); //printf("RCODE %i\n", rcode); // If the dst image was enlarged to fit the alignment, then shrink it back now. // Added by Shervin Emami, 17Nov2010. if (enlarged) { //std::cout << "w=" << dst->width << ", h=" << dst->height << ". orig w=" << origW << ", h=" << origH << std::endl; cvResize(dst, tmpDst, CV_INTER_CUBIC); // Shrink the enlarged image back into the original dst image. cvReleaseImage(&dst); // Free the enlarged image. } }
CV_IMPL void cvAcc( const void* arr, void* sumarr, const void* maskarr ) { static CvFuncTable acc_tab; static CvBigFuncTable accmask_tab; static int inittab = 0; CV_FUNCNAME( "cvAcc" ); __BEGIN__; int type, sumdepth; int mat_step, sum_step, mask_step = 0; CvSize size; CvMat stub, *mat = (CvMat*)arr; CvMat sumstub, *sum = (CvMat*)sumarr; CvMat maskstub, *mask = (CvMat*)maskarr; if( !inittab ) { icvInitAddTable( &acc_tab, &accmask_tab ); inittab = 1; } if( !CV_IS_MAT( mat ) || !CV_IS_MAT( sum )) { int coi1 = 0, coi2 = 0; CV_CALL( mat = cvGetMat( mat, &stub, &coi1 )); CV_CALL( sum = cvGetMat( sum, &sumstub, &coi2 )); if( coi1 + coi2 != 0 ) CV_ERROR( CV_BadCOI, "" ); } if( CV_MAT_DEPTH( sum->type ) != CV_32F ) CV_ERROR( CV_BadDepth, "" ); if( !CV_ARE_CNS_EQ( mat, sum )) CV_ERROR( CV_StsUnmatchedFormats, "" ); sumdepth = CV_MAT_DEPTH( sum->type ); if( sumdepth != CV_32F && (maskarr != 0 || sumdepth != CV_64F)) CV_ERROR( CV_BadDepth, "Bad accumulator type" ); if( !CV_ARE_SIZES_EQ( mat, sum )) CV_ERROR( CV_StsUnmatchedSizes, "" ); size = cvGetMatSize( mat ); type = CV_MAT_TYPE( mat->type ); mat_step = mat->step; sum_step = sum->step; if( !mask ) { CvFunc2D_2A func=(CvFunc2D_2A)acc_tab.fn_2d[CV_MAT_DEPTH(type)]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "Unsupported type combination" ); size.width *= CV_MAT_CN(type); if( CV_IS_MAT_CONT( mat->type & sum->type )) { size.width *= size.height; mat_step = sum_step = CV_STUB_STEP; size.height = 1; } IPPI_CALL( func( mat->data.ptr, mat_step, sum->data.ptr, sum_step, size )); } else { CvFunc2D_3A func = (CvFunc2D_3A)accmask_tab.fn_2d[type]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); CV_CALL( mask = cvGetMat( mask, &maskstub )); if( !CV_IS_MASK_ARR( mask )) CV_ERROR( CV_StsBadMask, "" ); if( !CV_ARE_SIZES_EQ( mat, mask )) CV_ERROR( CV_StsUnmatchedSizes, "" ); mask_step = mask->step; if( CV_IS_MAT_CONT( mat->type & sum->type & mask->type )) { size.width *= size.height; mat_step = sum_step = mask_step = CV_STUB_STEP; size.height = 1; } IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, mask_step, sum->data.ptr, sum_step, size )); } __END__; }
CV_IMPL void cvAbsDiff( const void* srcarr1, const void* srcarr2, void* dstarr ) { static CvFuncTable adiff_tab; static int inittab = 0; CV_FUNCNAME( "cvAbsDiff" ); __BEGIN__; int coi1 = 0, coi2 = 0, coi3 = 0; CvMat srcstub1, *src1 = (CvMat*)srcarr1; CvMat srcstub2, *src2 = (CvMat*)srcarr2; CvMat dststub, *dst = (CvMat*)dstarr; int src1_step, src2_step, dst_step; CvSize size; int type; if( !inittab ) { icvInitAbsDiffTable( &adiff_tab ); inittab = 1; } CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi1 )); CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi2 )); CV_CALL( dst = cvGetMat( dst, &dststub, &coi3 )); if( coi1 != 0 || coi2 != 0 || coi3 != 0 ) CV_ERROR( CV_BadCOI, "" ); if( !CV_ARE_SIZES_EQ( src1, src2 ) ) CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); size = icvGetMatSize( src1 ); type = CV_ARR_TYPE(src1->type); if( !CV_ARE_SIZES_EQ( src1, dst )) CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); if( !CV_ARE_TYPES_EQ( src1, src2 )) CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); if( !CV_ARE_TYPES_EQ( src1, dst )) CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); size.width *= CV_ARR_CN( type ); src1_step = src1->step; src2_step = src2->step; dst_step = dst->step; if( CV_IS_ARR_CONT( src1->type & src2->type & dst->type )) { size.width *= size.height; size.height = 1; src1_step = src2_step = dst_step = CV_STUB_STEP; } { CvFunc2D_3A func = (CvFunc2D_3A) (adiff_tab.fn_2d[CV_ARR_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); IPPI_CALL( func( src1->data.ptr, src1_step, src2->data.ptr, src2_step, dst->data.ptr, dst_step, size )); } __END__; }
CV_IMPL double cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist ) { double result = 0; CV_FUNCNAME( "cvCheckPointPolygon" ); __BEGIN__; CvSeqBlock block; CvContour header; CvSeq* contour = (CvSeq*)_contour; CvSeqReader reader; int i, total, counter = 0; int is_float; double min_dist_num = FLT_MAX, min_dist_denom = 1; CvPoint ip = {0,0}; if( !CV_IS_SEQ(contour) ) { CV_CALL( contour = cvPointSeqFromMat( CV_SEQ_KIND_CURVE + CV_SEQ_FLAG_CLOSED, _contour, &header, &block )); } else if( CV_IS_SEQ_POLYGON(contour) ) { if( contour->header_size == sizeof(CvContour) && !measure_dist ) { CvRect r = ((CvContour*)contour)->rect; if( pt.x < r.x || pt.y < r.y || pt.x >= r.x + r.width || pt.y >= r.y + r.height ) return -100; } } else if( CV_IS_SEQ_CHAIN(contour) ) { CV_ERROR( CV_StsBadArg, "Chains are not supported. Convert them to polygonal representation using cvApproxChains()" ); } else CV_ERROR( CV_StsBadArg, "Input contour is neither a valid sequence nor a matrix" ); total = contour->total; is_float = CV_SEQ_ELTYPE(contour) == CV_32FC2; cvStartReadSeq( contour, &reader, -1 ); if( !is_float && !measure_dist && (ip.x = cvRound(pt.x)) == pt.x && (ip.y = cvRound(pt.y)) == pt.y ) { // the fastest "pure integer" branch CvPoint v0, v; CV_READ_SEQ_ELEM( v, reader ); for( i = 0; i < total; i++ ) { int dist; v0 = v; CV_READ_SEQ_ELEM( v, reader ); if( (v0.y <= ip.y && v.y <= ip.y) || (v0.y > ip.y && v.y > ip.y) || (v0.x < ip.x && v.x < ip.x) ) { if( ip.y == v.y && (ip.x == v.x || (ip.y == v0.y && ((v0.x <= ip.x && ip.x <= v.x) || (v.x <= ip.x && ip.x <= v0.x)))) ) EXIT; continue; } dist = (ip.y - v0.y)*(v.x - v0.x) - (ip.x - v0.x)*(v.y - v0.y); if( dist == 0 ) EXIT; if( v.y < v0.y ) dist = -dist; counter += dist > 0; } result = counter % 2 == 0 ? -100 : 100; } else { CvPoint2D32f v0, v; CvPoint iv; if( is_float ) { CV_READ_SEQ_ELEM( v, reader ); } else { CV_READ_SEQ_ELEM( iv, reader ); v = cvPointTo32f( iv ); } if( !measure_dist ) { for( i = 0; i < total; i++ ) { double dist; v0 = v; if( is_float ) { CV_READ_SEQ_ELEM( v, reader ); } else { CV_READ_SEQ_ELEM( iv, reader ); v = cvPointTo32f( iv ); } if( (v0.y <= pt.y && v.y <= pt.y) || (v0.y > pt.y && v.y > pt.y) || (v0.x < pt.x && v.x < pt.x) ) { if( pt.y == v.y && (pt.x == v.x || (pt.y == v0.y && ((v0.x <= pt.x && pt.x <= v.x) || (v.x <= pt.x && pt.x <= v0.x)))) ) EXIT; continue; } dist = (double)(pt.y - v0.y)*(v.x - v0.x) - (double)(pt.x - v0.x)*(v.y - v0.y); if( dist == 0 ) EXIT; if( v.y < v0.y ) dist = -dist; counter += dist > 0; } result = counter % 2 == 0 ? -100 : 100; } else { for( i = 0; i < total; i++ ) { double dx, dy, dx1, dy1, dx2, dy2, dist_num, dist_denom = 1; v0 = v; if( is_float ) { CV_READ_SEQ_ELEM( v, reader ); } else { CV_READ_SEQ_ELEM( iv, reader ); v = cvPointTo32f( iv ); } dx = v.x - v0.x; dy = v.y - v0.y; dx1 = pt.x - v0.x; dy1 = pt.y - v0.y; dx2 = pt.x - v.x; dy2 = pt.y - v.y; if( dx1*dx + dy1*dy <= 0 ) dist_num = dx1*dx1 + dy1*dy1; else if( dx2*dx + dy2*dy >= 0 ) dist_num = dx2*dx2 + dy2*dy2; else { dist_num = (dy1*dx - dx1*dy); dist_num *= dist_num; dist_denom = dx*dx + dy*dy; } if( dist_num*min_dist_denom < min_dist_num*dist_denom ) { min_dist_num = dist_num; min_dist_denom = dist_denom; if( min_dist_num == 0 ) break; } if( (v0.y <= pt.y && v.y <= pt.y) || (v0.y > pt.y && v.y > pt.y) || (v0.x < pt.x && v.x < pt.x) ) continue; dist_num = dy1*dx - dx1*dy; if( dy < 0 ) dist_num = -dist_num; counter += dist_num > 0; } result = sqrt(min_dist_num/min_dist_denom); if( counter % 2 == 0 ) result = -result; } } __END__; return result; }
CvIntHaarClassifier* icvLoadTreeCascadeClassifier( const char* filename, int step, int* splits ) { CvTreeCascadeClassifier* ptr = NULL; CvTreeCascadeNode** nodes = NULL; CV_FUNCNAME( "icvLoadTreeCascadeClassifier" ); __BEGIN__; size_t data_size; CvStageHaarClassifier* stage; char stage_name[PATH_MAX]; char* suffix; int i, num; FILE* f; int result, parent=0, next=0; int stub; if( !splits ) splits = &stub; *splits = 0; data_size = sizeof( *ptr ); CV_CALL( ptr = (CvTreeCascadeClassifier*) cvAlloc( data_size ) ); memset( ptr, 0, data_size ); ptr->eval = icvEvalTreeCascadeClassifier; ptr->release = icvReleaseTreeCascadeClassifier; sprintf( stage_name, "%s/", filename ); suffix = stage_name + strlen( stage_name ); for( i = 0; ; i++ ) { sprintf( suffix, "%d/%s", i, CV_STAGE_CART_FILE_NAME ); f = fopen( stage_name, "r" ); if( !f ) break; fclose( f ); } num = i; if( num < 1 ) EXIT; data_size = sizeof( *nodes ) * num; CV_CALL( nodes = (CvTreeCascadeNode**) cvAlloc( data_size ) ); for( i = 0; i < num; i++ ) { sprintf( suffix, "%d/%s", i, CV_STAGE_CART_FILE_NAME ); f = fopen( stage_name, "r" ); CV_CALL( stage = (CvStageHaarClassifier*) icvLoadCARTStageHaarClassifierF( f, step ) ); result = ( f && stage ) ? fscanf( f, "%d%d", &parent, &next ) : 0; if( f ) fclose( f ); if( result != 2 ) { num = i; break; } printf( "Stage %d loaded\n", i ); if( parent >= i || (next != -1 && next != i + 1) ) CV_ERROR( CV_StsError, "Invalid tree links" ); CV_CALL( nodes[i] = icvCreateTreeCascadeNode() ); nodes[i]->stage = stage; nodes[i]->idx = i; nodes[i]->parent = (parent != -1 ) ? nodes[parent] : NULL; nodes[i]->next = ( next != -1 ) ? nodes[i] : NULL; nodes[i]->child = NULL; } for( i = 0; i < num; i++ ) { if( nodes[i]->next ) { (*splits)++; nodes[i]->next = nodes[i+1]; } if( nodes[i]->parent && nodes[i]->parent->child == NULL ) { nodes[i]->parent->child = nodes[i]; } } ptr->root = nodes[0]; ptr->next_idx = num; __END__; cvFree( &nodes ); return (CvIntHaarClassifier*) ptr; }
// Function cvCreateFGDStatModel initializes foreground detection process // parameters: // first_frame - frame from video sequence // parameters - (optional) if NULL default parameters of the algorithm will be used // p_model - pointer to CvFGDStatModel structure CV_IMPL CvBGStatModel* cvCreateFGDStatModel( IplImage* first_frame, CvFGDStatModelParams* parameters ) { CvFGDStatModel* p_model = 0; CV_FUNCNAME( "cvCreateFGDStatModel" ); __BEGIN__; int i, j, k, pixel_count, buf_size; CvFGDStatModelParams params; if( !CV_IS_IMAGE(first_frame) ) CV_ERROR( CV_StsBadArg, "Invalid or NULL first_frame parameter" ); if (first_frame->nChannels != 3) CV_ERROR( CV_StsBadArg, "first_frame must have 3 color channels" ); // Initialize parameters: if( parameters == NULL ) { params.Lc = CV_BGFG_FGD_LC; params.N1c = CV_BGFG_FGD_N1C; params.N2c = CV_BGFG_FGD_N2C; params.Lcc = CV_BGFG_FGD_LCC; params.N1cc = CV_BGFG_FGD_N1CC; params.N2cc = CV_BGFG_FGD_N2CC; params.delta = CV_BGFG_FGD_DELTA; params.alpha1 = CV_BGFG_FGD_ALPHA_1; params.alpha2 = CV_BGFG_FGD_ALPHA_2; params.alpha3 = CV_BGFG_FGD_ALPHA_3; params.T = CV_BGFG_FGD_T; params.minArea = CV_BGFG_FGD_MINAREA; params.is_obj_without_holes = 1; params.perform_morphing = 1; } else { params = *parameters; } CV_CALL( p_model = (CvFGDStatModel*)cvAlloc( sizeof(*p_model) )); memset( p_model, 0, sizeof(*p_model) ); p_model->type = CV_BG_MODEL_FGD; p_model->release = (CvReleaseBGStatModel)icvReleaseFGDStatModel; p_model->update = (CvUpdateBGStatModel)icvUpdateFGDStatModel;; p_model->params = params; // Initialize storage pools: pixel_count = first_frame->width * first_frame->height; buf_size = pixel_count*sizeof(p_model->pixel_stat[0]); CV_CALL( p_model->pixel_stat = (CvBGPixelStat*)cvAlloc(buf_size) ); memset( p_model->pixel_stat, 0, buf_size ); buf_size = pixel_count*params.N2c*sizeof(p_model->pixel_stat[0].ctable[0]); CV_CALL( p_model->pixel_stat[0].ctable = (CvBGPixelCStatTable*)cvAlloc(buf_size) ); memset( p_model->pixel_stat[0].ctable, 0, buf_size ); buf_size = pixel_count*params.N2cc*sizeof(p_model->pixel_stat[0].cctable[0]); CV_CALL( p_model->pixel_stat[0].cctable = (CvBGPixelCCStatTable*)cvAlloc(buf_size) ); memset( p_model->pixel_stat[0].cctable, 0, buf_size ); for( i = 0, k = 0; i < first_frame->height; i++ ) { for( j = 0; j < first_frame->width; j++, k++ ) { p_model->pixel_stat[k].ctable = p_model->pixel_stat[0].ctable + k*params.N2c; p_model->pixel_stat[k].cctable = p_model->pixel_stat[0].cctable + k*params.N2cc; } } // Init temporary images: CV_CALL( p_model->Ftd = cvCreateImage(cvSize(first_frame->width, first_frame->height), IPL_DEPTH_8U, 1)); CV_CALL( p_model->Fbd = cvCreateImage(cvSize(first_frame->width, first_frame->height), IPL_DEPTH_8U, 1)); CV_CALL( p_model->foreground = cvCreateImage(cvSize(first_frame->width, first_frame->height), IPL_DEPTH_8U, 1)); CV_CALL( p_model->background = cvCloneImage(first_frame)); CV_CALL( p_model->prev_frame = cvCloneImage(first_frame)); CV_CALL( p_model->storage = cvCreateMemStorage()); __END__; if( cvGetErrStatus() < 0 ) { CvBGStatModel* base_ptr = (CvBGStatModel*)p_model; if( p_model && p_model->release ) p_model->release( &base_ptr ); else cvFree( &p_model ); p_model = 0; } return (CvBGStatModel*)p_model; }
CV_IMPL CvSeq* cvSegmentImage(const CvArr* srcarr, CvArr* dstarr, double canny_threshold, double ffill_threshold, CvMemStorage* storage) { CvSeq* root = 0; CvMat* gray = 0; CvMat* canny = 0; //CvMat* temp = 0; void* stack = 0; CV_FUNCNAME("cvSegmentImage"); __BEGIN__; CvMat srcstub, *src; CvMat dststub, *dst; CvMat* mask; CvSize size; CvPoint pt; int ffill_lw_up = cvRound(fabs(ffill_threshold)); CvSeq* prev_seq = 0; CV_CALL(src = cvGetMat(srcarr, &srcstub)); CV_CALL(dst = cvGetMat(dstarr, &dststub)); size = cvGetSize(src); CV_CALL(gray = cvCreateMat(size.height, size.width, CV_8UC1)); CV_CALL(canny = cvCreateMat(size.height, size.width, CV_8UC1)); //CV_CALL( temp = cvCreateMat( size.height/2, size.width/2, CV_8UC3 )); CV_CALL(stack = cvAlloc(size.width * size.height * sizeof(Seg))); cvCvtColor(src, gray, CV_BGR2GRAY); cvCanny(gray, canny, 0/*canny_threshold*0.4*/, canny_threshold, 3); cvThreshold(canny, canny, 1, 1, CV_THRESH_BINARY); //cvZero( canny ); //color_derv( src, canny, canny_threshold ); //cvPyrDown( src, temp ); //cvPyrUp( temp, dst ); //src = dst; mask = canny; // a new name for new role // make a non-zero border. cvRectangle(mask, cvPoint(0, 0), cvPoint(size.width - 1, size.height - 1), cvScalarAll(1), 1); for (pt.y = 0; pt.y < size.height; pt.y++) { for (pt.x = 0; pt.x < size.width; pt.x++) { if (mask->data.ptr[mask->step* pt.y + pt.x] == 0) { CvConnectedComp region; int avgVal[3] = { 0, 0, 0 }; icvSegmFloodFill_Stage1(src->data.ptr, src->step, mask->data.ptr, mask->step, size, pt, avgVal, ffill_lw_up, ffill_lw_up, ®ion, stack); /*avgVal[0] = (avgVal[0] + 15) & -32; if( avgVal[0] > 255 ) avgVal[0] = 255; avgVal[1] = (avgVal[1] + 15) & -32; if( avgVal[1] > 255 ) avgVal[1] = 255; avgVal[2] = (avgVal[2] + 15) & -32; if( avgVal[2] > 255 ) avgVal[2] = 255;*/ if (storage) { CvSeq* tmpseq = icvGetComponent(mask->data.ptr, mask->step, region.rect, storage); if (tmpseq != 0) { ((CvContour*)tmpseq)->color = avgVal[0] + (avgVal[1] << 8) + (avgVal[2] << 16); tmpseq->h_prev = prev_seq; if (prev_seq) { prev_seq->h_next = tmpseq; } else { root = tmpseq; } prev_seq = tmpseq; } } icvSegmFloodFill_Stage2(dst->data.ptr, dst->step, mask->data.ptr, mask->step, size, avgVal, region.rect); } } } __END__; //cvReleaseMat( &temp ); cvReleaseMat(&gray); cvReleaseMat(&canny); cvFree(&stack); return root; }
CV_IMPL void cvSVD( CvArr* aarr, CvArr* warr, CvArr* uarr, CvArr* varr, int flags ) { uchar* buffer = 0; int local_alloc = 0; CV_FUNCNAME( "cvSVD" ); __BEGIN__; CvMat astub, *a = (CvMat*)aarr; CvMat wstub, *w = (CvMat*)warr; CvMat ustub, *u = (CvMat*)uarr; CvMat vstub, *v = (CvMat*)varr; CvMat tmat; uchar* tw = 0; int type, nm, mn; int buf_size, pix_size; int t_svd = 0; // special case: a->rows < a->cols if( !CV_IS_ARR( a )) CV_CALL( a = cvGetMat( a, &astub )); if( !CV_IS_ARR( w )) CV_CALL( w = cvGetMat( w, &wstub )); if( !CV_ARE_TYPES_EQ( a, w )) CV_ERROR( CV_StsUnmatchedFormats, "" ); nm = MIN( a->width, a->height ); mn = MAX( a->width, a->height ); if( (w->width == 1 || w->height == 1) && CV_IS_ARR_CONT( w->type ) && w->width*w->height == nm ) { tw = w->data.ptr; } else if( !CV_ARE_SIZES_EQ( w, a )) { CV_ERROR( CV_StsBadSize, "W must be either continuous vector of " "size MIN(A->width,A->height) or matrix of " "the same size as A" ); } if( u ) { if( !CV_IS_ARR( u )) CV_CALL( u = cvGetMat( u, &ustub )); if( !CV_ARE_TYPES_EQ( a, u )) CV_ERROR( CV_StsUnmatchedFormats, "" ); if( u->width != u->height || u->height != a->height ) CV_ERROR( CV_StsUnmatchedSizes, "U matrix must be square and have the same " "linear size as number of rows in A" ); if( u->data.ptr == a->data.ptr ) CV_ERROR( CV_StsBadArg, "U can not be equal A" ); } else { u = &ustub; u->data.ptr = 0; u->step = 0; } if( v ) { if( !CV_IS_ARR( v )) CV_CALL( v = cvGetMat( v, &vstub )); if( !CV_ARE_TYPES_EQ( a, v )) CV_ERROR( CV_StsUnmatchedFormats, "" ); if( v->width != v->height || v->width != a->width ) CV_ERROR( CV_StsUnmatchedSizes, "V matrix must be square and have the same " "linear size as number of columns in A" ); if( v->data.ptr == a->data.ptr || v->data.ptr == u->data.ptr ) CV_ERROR( CV_StsBadArg, "V can not be equal U or A" ); } else { v = &vstub; v->data.ptr = 0; v->step = 0; } type = CV_ARR_TYPE( a->type ); pix_size = icvPixSize[type]; buf_size = nm*2 + mn; if( a->rows < a->cols ) { CvMat* t; CV_SWAP( u, v, t ); flags = (flags & CV_SVD_U_T ? CV_SVD_V_T : 0)| (flags & CV_SVD_V_T ? CV_SVD_U_T : 0); t_svd = 1; } if( !(flags & CV_SVD_MODIFY_A) ) buf_size += a->width*a->height; buf_size *= pix_size; if( buf_size <= CV_MAX_LOCAL_SIZE ) { buffer = (uchar*)alloca( buf_size ); local_alloc = 1; } else { CV_CALL( buffer = (uchar*)cvAlloc( buf_size )); } if( !(flags & CV_SVD_MODIFY_A) ) { if( !t_svd ) { cvInitMatHeader( &tmat, a->height, a->width, type, buffer + (nm*2 + mn)*pix_size ); cvCopy( a, &tmat ); } else { cvInitMatHeader( &tmat, a->width, a->height, type, buffer + (nm*2 + mn)*pix_size ); cvT( a, &tmat ); } a = &tmat; } if( !tw ) tw = buffer + (nm + mn)*pix_size; if( type == CV_32FC1 ) { IPPI_CALL( icvSVD_32f( a->data.fl, a->step/sizeof(float), (float*)tw, u->data.fl, u->step/sizeof(float), v->data.fl, v->step/sizeof(float), icvGetMatSize(a), (float*)buffer )); } else if( type == CV_64FC1 ) { IPPI_CALL( icvSVD_64f( a->data.db, a->step/sizeof(double), (double*)tw, u->data.db, u->step/sizeof(double), v->data.db, v->step/sizeof(double), icvGetMatSize(a), (double*)buffer )); } else { CV_ERROR( CV_StsUnsupportedFormat, "" ); } if( tw != w->data.ptr ) { cvSetZero( w ); if( type == CV_32FC1 ) for( int i = 0; i < nm; i++ ) ((float*)(w->data.ptr + i*w->step))[i] = ((float*)tw)[i]; else for( int i = 0; i < nm; i++ ) ((double*)(w->data.ptr + i*w->step))[i] = ((double*)tw)[i]; } if( u->data.ptr ) { if( !(flags & CV_SVD_U_T)) cvT( u, u ); CV_CHECK_NANS( u ); } if( v->data.ptr) { if( !(flags & CV_SVD_V_T)) cvT( v, v ); CV_CHECK_NANS( v ); } CV_CHECK_NANS( w ); __END__; if( buffer && !local_alloc ) cvFree( (void**)&buffer ); }
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; }
void OptFlowEMD::calculate_flow(IplImage* imageT, IplImage* imageTMinus1, IplImage* velx, IplImage* vely, IplImage* abs){ #ifdef __CV_BEGIN__ __CV_BEGIN__ #else __BEGIN__ #endif CV_FUNCNAME( "OptFlowGenGrad::calculate_flow" ); CvMat stubA, *srcA = (CvMat*)imageT; // stubA takes the new header data for the matrix according to ROI CvMat stubB, *srcB = (CvMat*)imageTMinus1; CvMat stubx, *vel_x = (CvMat*)velx; CvMat stuby, *vel_y = (CvMat*)vely; CvMat stubAbs, *abs_ = NULL; if (abs != NULL) abs_ = (CvMat*)abs; // see GetMat function doc: This returns a matrix header with the current image ROI! // this gives basically a view on the ROI, stubA takes the header data of the matrix // srcA is pointed to this new 'augmented' data-header CV_CALL( srcA = cvGetMat( srcA, &stubA )); CV_CALL( srcB = cvGetMat( srcB, &stubB )); CV_CALL( vel_x = cvGetMat( vel_x, &stubx )); CV_CALL( vel_y = cvGetMat( vel_y, &stuby )); if (abs_ != NULL) CV_CALL( abs_ = cvGetMat ( abs_, &stubAbs )); if( !CV_ARE_TYPES_EQ( srcA, srcB )) CV_ERROR( CV_StsUnmatchedFormats, "Source images have different formats" ); if( !CV_ARE_TYPES_EQ( vel_x, vel_y )) CV_ERROR( CV_StsUnmatchedFormats, "Destination images have different formats" ); if (abs_ != NULL) if (!CV_ARE_TYPES_EQ( vel_x, abs_)) CV_ERROR( CV_StsUnmatchedFormats, "Destination images have different formats" ); if( !CV_ARE_SIZES_EQ( srcA, srcB ) || !CV_ARE_SIZES_EQ( vel_x, vel_y ) || !CV_ARE_SIZES_EQ( srcA, vel_x )) CV_ERROR( CV_StsUnmatchedSizes, "Some images have different sizes" ); if(abs_ != NULL) if (!CV_ARE_SIZES_EQ( srcA, abs_)) CV_ERROR( CV_StsUnmatchedSizes, "Some images have different sizes" ); if( CV_MAT_TYPE( srcA->type ) != CV_8UC1) CV_ERROR( CV_StsUnsupportedFormat, "Source images must have 8uC1 type"); if( CV_MAT_TYPE( vel_x->type ) != CV_32FC1 ) CV_ERROR( CV_StsUnsupportedFormat, "Destination images must have 32fC1 type" ); if( srcA->step != srcB->step || vel_x->step != vel_y->step) CV_ERROR( CV_BadStep, "source and destination images have different step" ); if (abs_ != NULL) if (vel_x->step != abs_->step) CV_ERROR( CV_BadStep, "source and destination images have different step" ); if (abs_ != NULL){ IPPI_CALL( calcOptFlowEMD( (uchar*)srcA->data.ptr, (uchar*)srcB->data.ptr, srcA->step, cvGetMatSize( srcA ), vel_x->data.fl, vel_y->data.fl, vel_x->step, abs_->data.fl)); } else{ IPPI_CALL( calcOptFlowEMD( (uchar*)srcA->data.ptr, (uchar*)srcB->data.ptr, srcA->step, cvGetMatSize( srcA ), vel_x->data.fl, vel_y->data.fl, vel_x->step, NULL)); } #ifdef __CV_END__ __CV_END__ #else __END__ #endif }
CvPoint* cvDRLSE(const CvArr * image, const CvArr * mask, int *length, double lambda, double alfa, double epsilon, int timestep, int ITER_ext, int ITER_int, int flag) { IplImage sstub1, sstub2, *msk, *img, *marker, *levelset; CvMat *ones, *Ix, *Iy, *phi, *f, *g; CvSize size; int comp_count =0, iStep; float* fPtr; CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = 0; CvPoint pt= cvPoint(0,0), *point=NULL; double mu = 0.2f/double(timestep); char c; CV_FUNCNAME( "cvDRLSE" ); __BEGIN__; CV_CALL( msk = cvGetImage(mask, &sstub1 )); CV_CALL( img = cvGetImage(image, &sstub2 )); cvSmooth(img, img, CV_GAUSSIAN, 5, 5, 1.5f); size = cvGetSize(img); levelset = cvCreateImage(size, IPL_DEPTH_8U, 1); ones = cvCreateMat(size.height, size.width, CV_32FC1); Ix = cvCreateMat(size.height, size.width, CV_32FC1); Iy = cvCreateMat(size.height, size.width, CV_32FC1); phi = cvCreateMat(size.height, size.width, CV_32FC1); f = cvCreateMat(size.height, size.width, CV_32FC1); g = cvCreateMat(size.height, size.width, CV_32FC1); marker = cvCreateImage(size, IPL_DEPTH_32S, 1); cvSet(ones, cvScalar(1.0f)); cvSobel(img, Ix, 1, 0, 1); cvSobel(img, Iy, 0, 1, 1); cvMul(Ix, Ix, Ix, 0.25f*0.25f); cvMul(Iy, Iy, Iy, 0.25f*0.25f); cvAdd(Ix, Iy, f); cvAdd(f, ones, f); cvDiv(NULL, f, g, 1.0f); cvFindContours( msk, storage, &contours, sizeof(CvContour),CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); cvZero(marker); for( ; contours != 0; contours = contours->h_next, comp_count++ ) { cvDrawContours( marker, contours, cvScalarAll(255),cvScalarAll(255), -1, -1, 8); } iStep = phi->step/sizeof(fPtr[0]); fPtr = phi->data.fl; for (int j=0; j<size.height; j++) for (int i=0; i<size.width; i++) { int idx = CV_IMAGE_ELEM( marker, int, j, i ); if (idx >0 ) if (flag == CV_LSE_SHR) fPtr[i+iStep*j]=-2.0f; else fPtr[i+iStep*j]=2.0f; else if (flag == CV_LSE_SHR) fPtr[i+iStep*j]=2.0f; else fPtr[i+iStep*j]=-2.0f; } for (int i=0; i<ITER_ext; i++) { cvDrlse_edge(phi, g, phi, lambda, mu, alfa, epsilon, timestep, ITER_int); loadBar(i+1, ITER_ext, 50); } cvDrlse_edge(phi, g, phi, lambda, mu, 0.0f, epsilon, timestep, ITER_int); cvZero(msk); if (flag == CV_LSE_SHR) cvThreshold(phi, msk, 0.0f, 255, CV_THRESH_BINARY_INV); else cvThreshold(phi, msk, 0.0f, 255, CV_THRESH_BINARY); cvFindContours(msk, storage, &contours, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); if(!contours) return 0; *length = contours->total; //if(*length<10) return 0; point = new CvPoint[*length]; CvSeqReader reader; cvStartReadSeq(contours, &reader); for (int i = 0; i < *length; i++){ CV_READ_SEQ_ELEM(pt, reader); point[i]=pt; } //clean up cvReleaseMemStorage(&storage); cvReleaseImage(&marker); cvReleaseMat(&Ix); cvReleaseMat(&Iy); cvReleaseMat(&f); cvReleaseMat(&g); cvReleaseMat(&phi); cvReleaseMat(&ones); return point; __END__; }
CV_IMPL void cvDrlse_edge(CvArr * srcphi, CvArr * srcgrad, CvArr * dstarr, double lambda, double mu, double alfa, double epsilon, int timestep, int iter) { CV_FUNCNAME( "cvDrlse_edge" ); __BEGIN__; CvMat sstub1, sstub2, *phi, *grad; CvMat dstub, *dst; CvMat *gradx=0, *grady=0, *phi_0=0, *phix=0, *phiy=0; CvMat *s=0, *Nx=0, *Ny=0, *curvature=0, *distRegTerm=0; CvMat *diracPhi=0, *areaTerm=0, *edgeTerm=0; CvMat *temp1=0, *temp2=0, *temp3=0, *ones=0; CvSize size; int i; CV_CALL( phi = cvGetMat(srcphi, &sstub1 )); CV_CALL( grad = cvGetMat(srcgrad, &sstub2 )); CV_CALL( dst = cvGetMat(dstarr, &dstub)); if( CV_MAT_TYPE(phi->type) != CV_32FC1) CV_ERROR( CV_StsUnsupportedFormat, "Only-32bit, 1-channel input images are supported" ); if( CV_MAT_TYPE(grad->type) != CV_32FC1) CV_ERROR( CV_StsUnsupportedFormat, "Only-32bit, 1-channel input images are supported" ); if( !CV_ARE_SIZES_EQ( phi, grad )) CV_ERROR( CV_StsUnmatchedSizes, "The input images must have the same size" ); size = cvGetMatSize( phi ); //Initialization gradx = cvCreateMat(size.height, size.width, CV_32FC1 ); grady = cvCreateMat(size.height, size.width, CV_32FC1 ); phi_0 = cvCreateMat(size.height, size.width, CV_32FC1 ); phix = cvCreateMat(size.height, size.width, CV_32FC1 ); phiy = cvCreateMat(size.height, size.width, CV_32FC1 ); Nx = cvCreateMat(size.height, size.width, CV_32FC1 ); Ny = cvCreateMat(size.height, size.width, CV_32FC1 ); s = cvCreateMat(size.height, size.width, CV_32FC1 ); curvature= cvCreateMat(size.height, size.width, CV_32FC1 ); distRegTerm= cvCreateMat(size.height, size.width, CV_32FC1 ); diracPhi = cvCreateMat(size.height, size.width, CV_32FC1 ); areaTerm = cvCreateMat(size.height, size.width, CV_32FC1 ); edgeTerm = cvCreateMat(size.height, size.width, CV_32FC1 ); temp1 = cvCreateMat(size.height, size.width, CV_32FC1 ); temp2 = cvCreateMat(size.height, size.width, CV_32FC1 ); temp3 = cvCreateMat(size.height, size.width, CV_32FC1 ); ones = cvCreateMat(size.height, size.width, CV_32FC1 ); cvSetZero(gradx); cvSetZero(grady); cvSetZero(phix); cvSetZero(phiy); cvSetZero(Nx); cvSetZero(Ny); cvSetZero(s); cvSetZero(curvature); cvSetZero(distRegTerm); cvSetZero(diracPhi); cvSetZero(areaTerm); cvSetZero(edgeTerm); cvSetZero(temp1); cvSetZero(temp2); cvSetZero(temp3); cvSet(ones, cvScalar(1.0f)); //--------------BEGIN---------------------- cvSobel(grad, gradx, 1, 0, 1); cvSobel(grad, grady, 0, 1, 1); cvMul(gradx, ones, gradx, 0.25f); cvMul(grady, ones, grady, 0.25f); cvCopy(phi, dst); for(i=0; i<iter; i++){ cvNeumannBoundCond(dst, dst); cvSobel(dst, phix, 1, 0, 1); cvSobel(dst, phiy, 0, 1, 1); cvCalS(dst,s); cvDiv(phix, s, Nx, 0.25f); cvDiv(phiy, s, Ny, 0.25f); cvCurvature(Nx, Ny, curvature); cvDistReg(dst, distRegTerm); cvDirac(dst, diracPhi, epsilon); //Compute driacPhi; cvMul(diracPhi, grad, areaTerm); //Compute areaTerm cvMul(gradx, Nx, gradx); //------------------// cvMul(grady, Ny, grady); // Computing // cvAdd(gradx, grady, temp1); // // cvMul(diracPhi, temp1, temp2); // edgeTerm // cvMul(areaTerm, curvature, temp3); // // cvAdd(temp2, temp3, edgeTerm); //------------------// cvMul(distRegTerm, ones, distRegTerm, mu); // distRegTerm = mu * distRegTerm cvMul(edgeTerm, ones, edgeTerm, lambda); // edgeTerm = lambda * edgeTerm cvMul(areaTerm, ones, areaTerm, alfa); // areaTerm = alfa * areaTerm cvAdd(distRegTerm, edgeTerm, temp1); cvAdd(temp1, areaTerm, temp2); // (distRegTerm + edgeTerm + areaTerm) cvMul(temp2, ones, temp2, double(timestep)); // timestep * (distRegTerm + edgeTerm + areaTerm) cvAdd(dst, temp2, dst); // phi = phi + timestep * (distRegTerm + edgeTerm + areaTerm) } //----------------END------------------------ // Clean up cvReleaseMat(&ones); cvReleaseMat(&phi_0); cvReleaseMat(&gradx); cvReleaseMat(&grady); cvReleaseMat(&phix); cvReleaseMat(&phiy); cvReleaseMat(&Nx); cvReleaseMat(&Ny); cvReleaseMat(&s); cvReleaseMat(&curvature); cvReleaseMat(&distRegTerm); cvReleaseMat(&diracPhi); cvReleaseMat(&areaTerm); cvReleaseMat(&edgeTerm); cvReleaseMat(&temp1); cvReleaseMat(&temp2); cvReleaseMat(&temp3); __END__; }
CV_IMPL void cvDistReg(const CvArr* srcarr, CvArr* dstarr) { CV_FUNCNAME("cvDistReg"); __BEGIN__; CvMat sstub, *src; CvMat dstub, *dst; CvMat* src_dx=0, *src_dy=0, *s=0, *ps=0; CvMat* dps_x=0, *dps_y=0, *del=0, *ones=0; CvSize size; int i, j, iStep_s, iStep_ps; float* fPtr_s, *fPtr_ps; float temp_s=0.0f, temp_ps=0.0f; float flag_s1=0.0f, flag_s2=0.0f, flag_ps1=0.0f, flag_ps2=0.0f; CV_CALL( src = cvGetMat(srcarr, &sstub )); CV_CALL( dst = cvGetMat(dstarr, &dstub )); if( CV_MAT_TYPE(src->type) != CV_32FC1) CV_ERROR( CV_StsUnsupportedFormat, "Only-32bit, 1-channel input images are supported" ); if( CV_MAT_TYPE(dst->type) != CV_32FC1) CV_ERROR( CV_StsUnsupportedFormat, "Only-32bit, 1-channel input images are supported" ); if( !CV_ARE_SIZES_EQ( src, dst )) CV_ERROR( CV_StsUnmatchedSizes, "The input images must have the same size" ); size = cvGetMatSize( src ); src_dx = cvCreateMat(size.height, size.width, CV_32FC1 ); src_dy = cvCreateMat(size.height, size.width, CV_32FC1 ); s = cvCreateMat(size.height, size.width, CV_32FC1 ); ps = cvCreateMat(size.height, size.width, CV_32FC1 ); dps_x = cvCreateMat(size.height, size.width, CV_32FC1 ); dps_y = cvCreateMat(size.height, size.width, CV_32FC1 ); del = cvCreateMat(size.height, size.width, CV_32FC1 ); ones = cvCreateMat(size.height, size.width, CV_32FC1 ); cvSetZero(src_dx); cvSetZero(src_dy); cvSetZero(s); cvSetZero(ps); cvSetZero(dps_x); cvSetZero(dps_y); cvSetZero(del); cvSet(ones, cvScalar(1.0f)); iStep_s = s->step / sizeof(fPtr_s[0]); fPtr_s = s->data.fl; iStep_ps= ps->step/ sizeof(fPtr_ps[0]); fPtr_ps = ps->data.fl; cvSobel(src, src_dx, 1, 0, 1); cvSobel(src, src_dy, 0, 1, 1); cvMul(src_dx, ones, src_dx, 0.25f); cvMul(src_dy, ones, src_dy, 0.25f); cvCalS(src,s); for (j=0; j<size.height; j++){ for (i=0; i<size.width; i++){ temp_s = fPtr_s[i+iStep_s*j]; if (int(temp_s*10000)>=0 && int(temp_s*10000)<=10000) { flag_s1 = 1.0f; } else { flag_s1 = 0.0f; } if (int(temp_s*10000) > 10000) { flag_s2 = 1.0f; } else { flag_s2 = 0.0f; } temp_ps = flag_s1*sin(2*PI*temp_s)/2/PI+flag_s2*(temp_s-1.0f); if (int(temp_ps*10000) == 0) { flag_ps1 = 0.0f; } else { flag_ps1 = 1.0f; } if (int(temp_s*10000) == 0) { flag_ps2 = 0.0f; } else { flag_ps2 = 1.0f; } fPtr_ps[i+iStep_ps*j] = (flag_ps1*temp_ps+1.0f-flag_ps1)/(flag_ps2*temp_s+1.0f-flag_ps2); if ((flag_ps2*temp_s+1.0f-flag_ps2)==0){ printf("Something wrong in last: temp_s = %f, flag_ps2 = %f\n", temp_s, flag_ps2); exit(0); } } } cvMul(ps, src_dx, dps_x); cvMul(ps, src_dy, dps_y); cvSub(dps_x, src_dx, dps_x); cvSub(dps_y, src_dy, dps_y); cvCurvature(dps_x, dps_y, dst); cvLaplace(src,del,1); cvMul(del, ones, del, 0.2f); cvAdd(dst, del, dst); cvReleaseMat(&src_dx); cvReleaseMat(&src_dy); cvReleaseMat(&s); cvReleaseMat(&ps); cvReleaseMat(&dps_x); cvReleaseMat(&dps_y); cvReleaseMat(&del); cvReleaseMat(&ones); __END__; }
CV_IMPL void cvRunningAvg( const void* arrY, void* arrU, double alpha, const void* maskarr ) { static CvFuncTable acc_tab; static CvBigFuncTable accmask_tab; static int inittab = 0; CV_FUNCNAME( "cvRunningAvg" ); __BEGIN__; int coi1, coi2; int type; int mat_step, sum_step, mask_step = 0; CvSize size; CvMat stub, *mat = (CvMat*)arrY; CvMat sumstub, *sum = (CvMat*)arrU; CvMat maskstub, *mask = (CvMat*)maskarr; if( !inittab ) { icvInitAddWeightedTable( &acc_tab, &accmask_tab ); inittab = 1; } CV_CALL( mat = cvGetMat( mat, &stub, &coi1 )); CV_CALL( sum = cvGetMat( sum, &sumstub, &coi2 )); if( coi1 != 0 || coi2 != 0 ) CV_ERROR( CV_BadCOI, "" ); if( !CV_ARE_CNS_EQ( mat, sum )) CV_ERROR( CV_StsUnmatchedFormats, "" ); if( CV_MAT_DEPTH( sum->type ) != CV_32F ) CV_ERROR( CV_BadDepth, "" ); if( !CV_ARE_SIZES_EQ( mat, sum )) CV_ERROR( CV_StsUnmatchedSizes, "" ); size = cvGetMatSize( mat ); type = CV_MAT_TYPE( mat->type ); mat_step = mat->step; sum_step = sum->step; if( !mask ) { CvAddWeightedFunc func = (CvAddWeightedFunc)acc_tab.fn_2d[CV_MAT_DEPTH(type)]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); size.width *= CV_MAT_CN(type); if( CV_IS_MAT_CONT( mat->type & sum->type )) { size.width *= size.height; mat_step = sum_step = CV_STUB_STEP; size.height = 1; } IPPI_CALL( func( mat->data.ptr, mat_step, sum->data.ptr, sum_step, size, (float)alpha )); } else { CvAddWeightedMaskFunc func = (CvAddWeightedMaskFunc)accmask_tab.fn_2d[type]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); CV_CALL( mask = cvGetMat( mask, &maskstub )); if( !CV_IS_MASK_ARR( mask )) CV_ERROR( CV_StsBadMask, "" ); if( !CV_ARE_SIZES_EQ( mat, mask )) CV_ERROR( CV_StsUnmatchedSizes, "" ); mask_step = mask->step; if( CV_IS_MAT_CONT( mat->type & sum->type & mask->type )) { size.width *= size.height; mat_step = sum_step = mask_step = CV_STUB_STEP; size.height = 1; } IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, mask_step, sum->data.ptr, sum_step, size, (float)alpha )); } __END__; }
CV_IMPL void cvMultiplyAcc( const void* arrA, const void* arrB, void* acc, const void* maskarr ) { static CvFuncTable acc_tab; static CvBigFuncTable accmask_tab; static int inittab = 0; CV_FUNCNAME( "cvMultiplyAcc" ); __BEGIN__; int coi1, coi2, coi3; int type; int mat1_step, mat2_step, sum_step, mask_step = 0; CvSize size; CvMat stub1, *mat1 = (CvMat*)arrA; CvMat stub2, *mat2 = (CvMat*)arrB; CvMat sumstub, *sum = (CvMat*)acc; CvMat maskstub, *mask = (CvMat*)maskarr; if( !inittab ) { icvInitAddProductTable( &acc_tab, &accmask_tab ); inittab = 1; } CV_CALL( mat1 = cvGetMat( mat1, &stub1, &coi1 )); CV_CALL( mat2 = cvGetMat( mat2, &stub2, &coi2 )); CV_CALL( sum = cvGetMat( sum, &sumstub, &coi3 )); if( coi1 != 0 || coi2 != 0 || coi3 != 0 ) CV_ERROR( CV_BadCOI, "" ); if( !CV_ARE_CNS_EQ( mat1, mat2 ) || !CV_ARE_CNS_EQ( mat1, sum )) CV_ERROR( CV_StsUnmatchedFormats, "" ); if( CV_MAT_DEPTH( sum->type ) != CV_32F ) CV_ERROR( CV_BadDepth, "" ); if( !CV_ARE_SIZES_EQ( mat1, sum ) || !CV_ARE_SIZES_EQ( mat2, sum )) CV_ERROR( CV_StsUnmatchedSizes, "" ); size = cvGetMatSize( mat1 ); type = CV_MAT_TYPE( mat1->type ); mat1_step = mat1->step; mat2_step = mat2->step; sum_step = sum->step; if( !mask ) { CvFunc2D_3A func = (CvFunc2D_3A)acc_tab.fn_2d[CV_MAT_DEPTH(type)]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); size.width *= CV_MAT_CN(type); if( CV_IS_MAT_CONT( mat1->type & mat2->type & sum->type )) { size.width *= size.height; mat1_step = mat2_step = sum_step = CV_STUB_STEP; size.height = 1; } IPPI_CALL( func( mat1->data.ptr, mat1_step, mat2->data.ptr, mat2_step, sum->data.ptr, sum_step, size )); } else { CvFunc2D_4A func = (CvFunc2D_4A)accmask_tab.fn_2d[type]; if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); CV_CALL( mask = cvGetMat( mask, &maskstub )); if( !CV_IS_MASK_ARR( mask )) CV_ERROR( CV_StsBadMask, "" ); if( !CV_ARE_SIZES_EQ( mat1, mask )) CV_ERROR( CV_StsUnmatchedSizes, "" ); mask_step = mask->step; if( CV_IS_MAT_CONT( mat1->type & mat2->type & sum->type & mask->type )) { size.width *= size.height; mat1_step = mat2_step = sum_step = mask_step = CV_STUB_STEP; size.height = 1; } IPPI_CALL( func( mat1->data.ptr, mat1_step, mat2->data.ptr, mat2_step, mask->data.ptr, mask_step, sum->data.ptr, sum_step, size )); } __END__; }
void icvConvertPointsHomogenious( const CvMat* src, CvMat* dst ) { CvMat* temp = 0; CvMat* denom = 0; CV_FUNCNAME( "cvConvertPointsHomogenious" ); __BEGIN__; int i, s_count, s_dims, d_count, d_dims; CvMat _src, _dst, _ones; CvMat* ones = 0; if( !CV_IS_MAT(src) ) CV_ERROR( !src ? CV_StsNullPtr : CV_StsBadArg, "The input parameter is not a valid matrix" ); if( !CV_IS_MAT(dst) ) CV_ERROR( !dst ? CV_StsNullPtr : CV_StsBadArg, "The output parameter is not a valid matrix" ); if( src == dst || src->data.ptr == dst->data.ptr ) { if( src != dst && (!CV_ARE_TYPES_EQ(src, dst) || !CV_ARE_SIZES_EQ(src,dst)) ) CV_ERROR( CV_StsBadArg, "Invalid inplace operation" ); EXIT; } if( src->rows > src->cols ) { if( !((src->cols > 1) ^ (CV_MAT_CN(src->type) > 1)) ) CV_ERROR( CV_StsBadSize, "Either the number of channels or columns or " "rows must be =1" ); s_dims = CV_MAT_CN(src->type)*src->cols; s_count = src->rows; } else { if( !((src->rows > 1) ^ (CV_MAT_CN(src->type) > 1)) ) CV_ERROR( CV_StsBadSize, "Either the number of channels or columns or " "rows must be =1" ); s_dims = CV_MAT_CN(src->type)*src->rows; s_count = src->cols; } if( src->rows == 1 || src->cols == 1 ) src = cvReshape( src, &_src, 1, s_count ); if( dst->rows > dst->cols ) { if( !((dst->cols > 1) ^ (CV_MAT_CN(dst->type) > 1)) ) CV_ERROR( CV_StsBadSize, "Either the number of channels or columns or " "rows in the input matrix must be =1" ); d_dims = CV_MAT_CN(dst->type)*dst->cols; d_count = dst->rows; } else { if( !((dst->rows > 1) ^ (CV_MAT_CN(dst->type) > 1)) ) CV_ERROR( CV_StsBadSize, "Either the number of channels or columns or " "rows in the output matrix must be =1" ); d_dims = CV_MAT_CN(dst->type)*dst->rows; d_count = dst->cols; } if( dst->rows == 1 || dst->cols == 1 ) dst = cvReshape( dst, &_dst, 1, d_count ); if( s_count != d_count ) CV_ERROR( CV_StsUnmatchedSizes, "Both matrices must have the " "same number of points" ); if( CV_MAT_DEPTH(src->type) < CV_32F || CV_MAT_DEPTH(dst->type) < CV_32F ) CV_ERROR( CV_StsUnsupportedFormat, "Both matrices must be floating-point " "(single or double precision)" ); if( s_dims < 2 || s_dims > 4 || d_dims < 2 || d_dims > 4 ) CV_ERROR( CV_StsOutOfRange, "Both input and output point dimensionality " "must be 2, 3 or 4" ); if( s_dims < d_dims - 1 || s_dims > d_dims + 1 ) CV_ERROR( CV_StsUnmatchedSizes, "The dimensionalities of input and output " "point sets differ too much" ); if( s_dims == d_dims - 1 ) { if( d_count == dst->rows ) { ones = cvGetSubRect( dst, &_ones, cvRect( s_dims, 0, 1, d_count )); dst = cvGetSubRect( dst, &_dst, cvRect( 0, 0, s_dims, d_count )); } else { ones = cvGetSubRect( dst, &_ones, cvRect( 0, s_dims, d_count, 1 )); dst = cvGetSubRect( dst, &_dst, cvRect( 0, 0, d_count, s_dims )); } } if( s_dims <= d_dims ) { if( src->rows == dst->rows && src->cols == dst->cols ) { if( CV_ARE_TYPES_EQ( src, dst ) ) cvCopy( src, dst ); else cvConvert( src, dst ); } else { if( !CV_ARE_TYPES_EQ( src, dst )) { CV_CALL( temp = cvCreateMat( src->rows, src->cols, dst->type )); cvConvert( src, temp ); src = temp; } cvTranspose( src, dst ); } if( ones ) cvSet( ones, cvRealScalar(1.) ); } else { int s_plane_stride, s_stride, d_plane_stride, d_stride, elem_size; if( !CV_ARE_TYPES_EQ( src, dst )) { CV_CALL( temp = cvCreateMat( src->rows, src->cols, dst->type )); cvConvert( src, temp ); src = temp; } elem_size = CV_ELEM_SIZE(src->type); if( s_count == src->cols ) s_plane_stride = src->step / elem_size, s_stride = 1; else s_stride = src->step / elem_size, s_plane_stride = 1; if( d_count == dst->cols ) d_plane_stride = dst->step / elem_size, d_stride = 1; else d_stride = dst->step / elem_size, d_plane_stride = 1; CV_CALL( denom = cvCreateMat( 1, d_count, dst->type )); if( CV_MAT_DEPTH(dst->type) == CV_32F ) { const float* xs = src->data.fl; const float* ys = xs + s_plane_stride; const float* zs = 0; const float* ws = xs + (s_dims - 1)*s_plane_stride; float* iw = denom->data.fl; float* xd = dst->data.fl; float* yd = xd + d_plane_stride; float* zd = 0; if( d_dims == 3 ) { zs = ys + s_plane_stride; zd = yd + d_plane_stride; } for( i = 0; i < d_count; i++, ws += s_stride ) { float t = *ws; iw[i] = t ? t : 1.f; } cvDiv( 0, denom, denom ); if( d_dims == 3 ) for( i = 0; i < d_count; i++ ) { float w = iw[i]; float x = *xs * w, y = *ys * w, z = *zs * w; xs += s_stride; ys += s_stride; zs += s_stride; *xd = x; *yd = y; *zd = z; xd += d_stride; yd += d_stride; zd += d_stride; } else for( i = 0; i < d_count; i++ ) { float w = iw[i]; float x = *xs * w, y = *ys * w; xs += s_stride; ys += s_stride; *xd = x; *yd = y; xd += d_stride; yd += d_stride; } } else { const double* xs = src->data.db; const double* ys = xs + s_plane_stride; const double* zs = 0; const double* ws = xs + (s_dims - 1)*s_plane_stride; double* iw = denom->data.db; double* xd = dst->data.db; double* yd = xd + d_plane_stride; double* zd = 0; if( d_dims == 3 ) { zs = ys + s_plane_stride; zd = yd + d_plane_stride; } for( i = 0; i < d_count; i++, ws += s_stride ) { double t = *ws; iw[i] = t ? t : 1.; } cvDiv( 0, denom, denom ); if( d_dims == 3 ) for( i = 0; i < d_count; i++ ) { double w = iw[i]; double x = *xs * w, y = *ys * w, z = *zs * w; xs += s_stride; ys += s_stride; zs += s_stride; *xd = x; *yd = y; *zd = z; xd += d_stride; yd += d_stride; zd += d_stride; } else for( i = 0; i < d_count; i++ ) { double w = iw[i]; double x = *xs * w, y = *ys * w; xs += s_stride; ys += s_stride; *xd = x; *yd = y; xd += d_stride; yd += d_stride; } } } __END__; cvReleaseMat( &denom ); cvReleaseMat( &temp ); }
// finds perspective transformation H between // the object plane and image plane, // so that (sxi,syi,s) ~ H*(Xi,Yi,1) void icvFindHomography( const CvMat* object_points, const CvMat* image_points, CvMat* __H ) { CvMat *_m = 0, *_M = 0; CvMat *_L2 = 0; CV_FUNCNAME( "cvFindHomography" ); __BEGIN__; int h_type; int i, k, count, count2; CvPoint2D64f *m, *M; CvPoint2D64f cm = {0,0}, sm = {0,0}; double inv_Hnorm[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; double H[9]; CvMat _inv_Hnorm = cvMat( 3, 3, CV_64FC1, inv_Hnorm ); CvMat _H = cvMat( 3, 3, CV_64FC1, H ); double LtL[9*9], LW[9], LV[9*9]; CvMat* _Lp; double* L; CvMat _LtL = cvMat( 9, 9, CV_64FC1, LtL ); CvMat _LW = cvMat( 9, 1, CV_64FC1, LW ); CvMat _LV = cvMat( 9, 9, CV_64FC1, LV ); CvMat _Hrem = cvMat( 3, 3, CV_64FC1, LV + 8*9 ); if( !CV_IS_MAT(image_points) || !CV_IS_MAT(object_points) || !CV_IS_MAT(__H) ) CV_ERROR( CV_StsBadArg, "one of arguments is not a valid matrix" ); h_type = CV_MAT_TYPE(__H->type); if( h_type != CV_32FC1 && h_type != CV_64FC1 ) CV_ERROR( CV_StsUnsupportedFormat, "Homography matrix must have 32fC1 or 64fC1 type" ); if( __H->rows != 3 || __H->cols != 3 ) CV_ERROR( CV_StsBadSize, "Homography matrix must be 3x3" ); count = MAX(image_points->cols, image_points->rows); count2 = MAX(object_points->cols, object_points->rows); if( count != count2 ) CV_ERROR( CV_StsUnmatchedSizes, "Numbers of image and object points do not match" ); CV_CALL( _m = cvCreateMat( 1, count, CV_64FC2 )); CV_CALL( icvConvertPointsHomogenious( image_points, _m )); m = (CvPoint2D64f*)_m->data.ptr; CV_CALL( _M = cvCreateMat( 1, count, CV_64FC2 )); CV_CALL( icvConvertPointsHomogenious( object_points, _M )); M = (CvPoint2D64f*)_M->data.ptr; // calculate the normalization transformation Hnorm. for( i = 0; i < count; i++ ) cm.x += m[i].x, cm.y += m[i].y; cm.x /= count; cm.y /= count; for( i = 0; i < count; i++ ) { double x = m[i].x - cm.x; double y = m[i].y - cm.y; sm.x += fabs(x); sm.y += fabs(y); } sm.x /= count; sm.y /= count; inv_Hnorm[0] = sm.x; inv_Hnorm[4] = sm.y; inv_Hnorm[2] = cm.x; inv_Hnorm[5] = cm.y; sm.x = 1./sm.x; sm.y = 1./sm.y; CV_CALL( _Lp = _L2 = cvCreateMat( 2*count, 9, CV_64FC1 ) ); L = _L2->data.db; for( i = 0; i < count; i++, L += 18 ) { double x = -(m[i].x - cm.x)*sm.x, y = -(m[i].y - cm.y)*sm.y; L[0] = L[9 + 3] = M[i].x; L[1] = L[9 + 4] = M[i].y; L[2] = L[9 + 5] = 1; L[9 + 0] = L[9 + 1] = L[9 + 2] = L[3] = L[4] = L[5] = 0; L[6] = x*M[i].x; L[7] = x*M[i].y; L[8] = x; L[9 + 6] = y*M[i].x; L[9 + 7] = y*M[i].y; L[9 + 8] = y; } if( count > 4 ) { cvMulTransposed( _L2, &_LtL, 1 ); _Lp = &_LtL; } _LW.rows = MIN(count*2, 9); cvSVD( _Lp, &_LW, 0, &_LV, CV_SVD_MODIFY_A + CV_SVD_V_T ); cvScale( &_Hrem, &_Hrem, 1./_Hrem.data.db[8] ); cvMatMul( &_inv_Hnorm, &_Hrem, &_H ); if( count > 4 ) { // reuse the available storage for jacobian and other vars CvMat _J = cvMat( 2*count, 8, CV_64FC1, _L2->data.db ); CvMat _err = cvMat( 2*count, 1, CV_64FC1, _L2->data.db + 2*count*8 ); CvMat _JtJ = cvMat( 8, 8, CV_64FC1, LtL ); CvMat _JtErr = cvMat( 8, 1, CV_64FC1, LtL + 8*8 ); CvMat _JtJW = cvMat( 8, 1, CV_64FC1, LW ); CvMat _JtJV = cvMat( 8, 8, CV_64FC1, LV ); CvMat _Hinnov = cvMat( 8, 1, CV_64FC1, LV + 8*8 ); for( k = 0; k < 10; k++ ) { double* J = _J.data.db, *err = _err.data.db; for( i = 0; i < count; i++, J += 16, err += 2 ) { double di = 1./(H[6]*M[i].x + H[7]*M[i].y + 1.); double _xi = (H[0]*M[i].x + H[1]*M[i].y + H[2])*di; double _yi = (H[3]*M[i].x + H[4]*M[i].y + H[5])*di; err[0] = m[i].x - _xi; err[1] = m[i].y - _yi; J[0] = M[i].x*di; J[1] = M[i].y*di; J[2] = di; J[8+3] = M[i].x; J[8+4] = M[i].y; J[8+5] = di; J[6] = -J[0]*_xi; J[7] = -J[1]*_xi; J[8+6] = -J[8+3]*_yi; J[8+7] = -J[8+4]*_yi; J[3] = J[4] = J[5] = J[8+0] = J[8+1] = J[8+2] = 0.; } icvGaussNewton( &_J, &_err, &_Hinnov, &_JtJ, &_JtErr, &_JtJW, &_JtJV ); for( i = 0; i < 8; i++ ) H[i] += _Hinnov.data.db[i]; } } cvConvert( &_H, __H ); __END__; cvReleaseMat( &_m ); cvReleaseMat( &_M ); cvReleaseMat( &_L2 ); }
CV_IMPL void cvMinEnclosingCircle( CvSeq * sequence, CvPoint2D32f * _center, float *_radius ) { const int max_iters = 20; CvSeqReader reader; int i, k, count; CvPoint *pt_left, *pt_right, *pt_top, *pt_bottom; CvPoint pt; CvPoint2D32f center = { 0, 0 }; CvPoint2D32f pts[8]; float radius = 0; if( _center ) _center->x = _center->y = 0.f; if( _radius ) *_radius = 0; CV_FUNCNAME( "cvMinEnclosingCircle" ); __BEGIN__; if( !sequence || !_center || !_radius ) CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR ); if( sequence->total <= 0 ) CV_ERROR_FROM_STATUS( CV_BADSIZE_ERR ); if( !CV_IS_SEQ_POINT_SET( sequence )) CV_ERROR_FROM_STATUS( CV_BADFLAG_ERR ); CV_CALL( cvStartReadSeq( sequence, &reader, 0 )); pt_left = pt_right = pt_top = pt_bottom = (CvPoint *) (reader.ptr); CV_READ_SEQ_ELEM( pt, reader ); count = sequence->total; for( i = 1; i < count; i++ ) { CvPoint *pt_ptr = (CvPoint *) (reader.ptr); CvPoint pt; CV_READ_SEQ_ELEM( pt, reader ); if( pt.x < pt_left->x ) pt_left = pt_ptr; if( pt.x > pt_right->x ) pt_right = pt_ptr; if( pt.y < pt_top->y ) pt_top = pt_ptr; if( pt.y > pt_bottom->y ) pt_bottom = pt_ptr; } pts[0] = icvCvtPoint32s_32f( *pt_left ); pts[1] = icvCvtPoint32s_32f( *pt_right ); pts[2] = icvCvtPoint32s_32f( *pt_top ); pts[3] = icvCvtPoint32s_32f( *pt_bottom ); for( k = 0; k < max_iters; k++ ) { icvFindEnslosingCicle4pts_32f( pts, ¢er, &radius ); cvStartReadSeq( sequence, &reader, 0 ); for( i = 0; i < count; i++ ) { CvPoint pt; CvPoint2D32f ptfl; CV_READ_SEQ_ELEM( pt, reader ); ptfl = icvCvtPoint32s_32f( pt ); if( !icvIsPtInCircle( ptfl, center, radius )) { pts[3] = ptfl; break; } } if( i == count ) break; } __CLEANUP__; __END__; *_center = center; *_radius = radius; }
CV_IMPL double cvPseudoInv( CvArr* srcarr, CvArr* dstarr, int flags ) { uchar* buffer = 0; int local_alloc = 0; double condition_number = 0; CV_FUNCNAME( "cvPseudoInv" ); __BEGIN__; CvMat astub, *a = (CvMat*)srcarr; CvMat bstub, *b = (CvMat*)dstarr; CvMat ustub, *u = &ustub; CvMat vstub, *v = &vstub; CvMat tmat; uchar* tw = 0; int type, n, m, nm, mn; int buf_size, pix_size; if( !CV_IS_ARR( a )) CV_CALL( a = cvGetMat( a, &astub )); if( !CV_IS_ARR( b )) CV_CALL( b = cvGetMat( b, &bstub )); if( !CV_ARE_TYPES_EQ( a, b )) CV_ERROR( CV_StsUnmatchedSizes, "" ); n = a->width; m = a->height; nm = MIN( n, m ); mn = MAX( n, m ); if( n != b->height || m != b->width ) CV_ERROR( CV_StsUnmatchedSizes, "" ); type = CV_ARR_TYPE( a->type ); pix_size = icvPixSize[type]; buf_size = nm*2 + mn + m*mn + n*n; if( !(flags & CV_SVD_MODIFY_A) ) buf_size += m*n; buf_size *= pix_size; if( buf_size <= CV_MAX_LOCAL_SIZE ) { buffer = (uchar*)alloca( buf_size ); local_alloc = 1; } else { CV_CALL( buffer = (uchar*)cvAlloc( buf_size )); } if( !(flags & CV_SVD_MODIFY_A) ) { cvInitMatHeader( &tmat, a->height, a->width, type, buffer + buf_size - n*m*pix_size ); cvCopy( a, &tmat ); a = &tmat; } tw = buffer + (nm + mn)*pix_size; cvInitMatHeader( u, m, m, type, tw + nm*pix_size ); cvInitMatHeader( v, n, n, type, u->data.ptr + m*mn*pix_size ); if( type == CV_32FC1 ) { IPPI_CALL( icvSVD_32f( a->data.fl, a->step/sizeof(float), (float*)tw, u->data.fl, u->step/sizeof(float), v->data.fl, v->step/sizeof(float), icvGetMatSize(a), (float*)buffer )); } else if( type == CV_64FC1 ) { IPPI_CALL( icvSVD_64f( a->data.db, a->step/sizeof(double), (double*)tw, u->data.db, u->step/sizeof(double), v->data.db, v->step/sizeof(double), icvGetMatSize(a), (double*)buffer )); } else { CV_ERROR( CV_StsUnsupportedFormat, "" ); } cvT( v, v ); cvGetRow( u, &tmat, 0 ); if( type == CV_32FC1 ) { for( int i = 0; i < nm; i++ ) { double t = ((float*)tw)[i]; tmat.data.ptr = u->data.ptr + i*u->step; t = t > FLT_EPSILON ? 1./t : 0; if( i == mn - 1 ) condition_number = t != 0 ? ((float*)tw)[0]*t : DBL_MAX; cvScale( &tmat, &tmat, t ); } } else { for( int i = 0; i < nm; i++ ) { double t = ((double*)tw)[i]; tmat.data.ptr = u->data.ptr + i*u->step; t = t > DBL_EPSILON ? 1./t : 0; if( i == mn - 1 ) condition_number = t != 0 ? ((double*)tw)[0]*t : DBL_MAX; cvScale( &tmat, &tmat, t ); } } u->height = n; if( n > m ) { cvGetSubArr( u, &tmat, cvRect( 0, m, m, n - m )); cvSetZero( &tmat ); } cvMatMulAdd( v, u, 0, b ); CV_CHECK_NANS( b ); __END__; if( buffer && !local_alloc ) cvFree( (void**)&buffer ); return condition_number; }
CV_IMPL CvScalar cvAvg( const void* img, const void* maskarr ) { CvScalar mean = {{0,0,0,0}}; static CvBigFuncTable mean_tab; static CvFuncTable meancoi_tab; static int inittab = 0; CV_FUNCNAME("cvAvg"); __BEGIN__; CvSize size; double scale; if( !maskarr ) { CV_CALL( mean = cvSum(img)); size = cvGetSize( img ); size.width *= size.height; scale = size.width ? 1./size.width : 0; mean.val[0] *= scale; mean.val[1] *= scale; mean.val[2] *= scale; mean.val[3] *= scale; } else { int type, coi = 0; int mat_step, mask_step; CvMat stub, maskstub, *mat = (CvMat*)img, *mask = (CvMat*)maskarr; if( !inittab ) { icvInitMeanMRTable( &mean_tab ); icvInitMeanCnCMRTable( &meancoi_tab ); inittab = 1; } if( !CV_IS_MAT(mat) ) CV_CALL( mat = cvGetMat( mat, &stub, &coi )); if( !CV_IS_MAT(mask) ) CV_CALL( mask = cvGetMat( mask, &maskstub )); if( !CV_IS_MASK_ARR(mask) ) CV_ERROR( CV_StsBadMask, "" ); if( !CV_ARE_SIZES_EQ( mat, mask ) ) CV_ERROR( CV_StsUnmatchedSizes, "" ); type = CV_MAT_TYPE( mat->type ); size = cvGetMatSize( mat ); mat_step = mat->step; mask_step = mask->step; if( CV_IS_MAT_CONT( mat->type & mask->type )) { size.width *= size.height; size.height = 1; mat_step = mask_step = CV_STUB_STEP; } if( CV_MAT_CN(type) == 1 || coi == 0 ) { CvFunc2D_2A1P func; if( CV_MAT_CN(type) > 4 ) CV_ERROR( CV_StsOutOfRange, "The input array must have at most 4 channels unless COI is set" ); func = (CvFunc2D_2A1P)(mean_tab.fn_2d[type]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, mask_step, size, mean.val )); } else { CvFunc2DnC_2A1P func = (CvFunc2DnC_2A1P)( meancoi_tab.fn_2d[CV_MAT_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, mask_step, size, CV_MAT_CN(type), coi, mean.val )); } } __END__; return mean; }
CV_IMPL int cvNamedWindow( const char* name, int flags ) { int result = 0; CV_FUNCNAME( "cvNamedWindow" ); if (!wasInitialized) cvInitSystem(0, NULL); // to be able to display a window, we need to be a 'faceful' application // http://lists.apple.com/archives/carbon-dev/2005/Jun/msg01414.html static bool switched_to_faceful = false; if (! switched_to_faceful) { ProcessSerialNumber psn = { 0, kCurrentProcess }; OSStatus ret = TransformProcessType (&psn, kProcessTransformToForegroundApplication ); if (ret == noErr) { SetFrontProcess( &psn ); switched_to_faceful = true; } else { fprintf(stderr, "Failed to tranform process type: %d\n", (int) ret); fflush (stderr); } } __BEGIN__; WindowRef outWindow = NULL; OSStatus err = noErr; Rect contentBounds = {100,100,320,440}; CvWindow* window; UInt wAttributes = 0; int len; const EventTypeSpec genericWindowEventHandler[] = { { kEventClassMouse, kEventMouseMoved}, { kEventClassMouse, kEventMouseUp}, { kEventClassMouse, kEventMouseDown}, { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowBoundsChanged }//FD }; if( !name ) CV_ERROR( CV_StsNullPtr, "NULL name string" ); if( icvFindWindowByName( name ) != 0 ){ result = 1; EXIT; } len = strlen(name); CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); memset( window, 0, sizeof(*window)); window->name = (char*)(window + 1); memcpy( window->name, name, len + 1 ); window->flags = flags; window->signature = CV_WINDOW_MAGIC_VAL; window->image = 0; window->last_key = 0; window->on_mouse = 0; window->on_mouse_param = 0; window->next = hg_windows; window->prev = 0; if( hg_windows ) hg_windows->prev = window; hg_windows = window; wAttributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute; err = CreateNewWindow ( kDocumentWindowClass,wAttributes,&contentBounds,&outWindow); if (err != noErr) fprintf(stderr,"Erreur while creating the window\n"); SetWindowTitleWithCFString(outWindow,CFStringCreateWithCString(NULL,name,kCFStringEncodingASCII)); if (err != noErr) fprintf(stdout,"Erreur SetWindowTitleWithCFString\n"); window->window = outWindow; err = InstallWindowEventHandler(outWindow, NewEventHandlerUPP(windowEventHandler), GetEventTypeCount(genericWindowEventHandler), genericWindowEventHandler, outWindow, NULL); ShowWindow( outWindow ); result = 1; __END__; return result; }
CV_IMPL void cvMinMaxLoc( const void* img, double* _minVal, double* _maxVal, CvPoint* _minLoc, CvPoint* _maxLoc, const void* mask ) { static CvFuncTable minmax_tab, minmaxcoi_tab; static CvFuncTable minmaxmask_tab, minmaxmaskcoi_tab; static int inittab = 0; CV_FUNCNAME("cvMinMaxLoc"); __BEGIN__; int type, depth, cn, coi = 0; int mat_step, mask_step = 0; CvSize size; CvMat stub, maskstub, *mat = (CvMat*)img, *matmask = (CvMat*)mask; CvPoint minLoc, maxLoc; double minVal = 0, maxVal = 0; if( !inittab ) { icvInitMinMaxIndxC1RTable( &minmax_tab ); icvInitMinMaxIndxCnCRTable( &minmaxcoi_tab ); icvInitMinMaxIndxC1MRTable( &minmaxmask_tab ); icvInitMinMaxIndxCnCMRTable( &minmaxmaskcoi_tab ); inittab = 1; } CV_CALL( mat = cvGetMat( mat, &stub, &coi )); type = CV_MAT_TYPE( mat->type ); depth = CV_MAT_DEPTH( type ); cn = CV_MAT_CN( type ); size = cvGetMatSize( mat ); if( cn > 1 && coi == 0 ) CV_ERROR( CV_StsBadArg, "" ); mat_step = mat->step; if( !mask ) { if( size.height == 1 ) mat_step = CV_STUB_STEP; if( CV_MAT_CN(type) == 1 || coi == 0 ) { CvFunc2D_1A4P func = (CvFunc2D_1A4P)(minmax_tab.fn_2d[depth]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, &minVal, &maxVal, &minLoc, &maxLoc )); } else { CvFunc2DnC_1A4P func = (CvFunc2DnC_1A4P)(minmaxcoi_tab.fn_2d[depth]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, cn, coi, &minVal, &maxVal, &minLoc, &maxLoc )); } } else { CV_CALL( matmask = cvGetMat( matmask, &maskstub )); if( !CV_IS_MASK_ARR( matmask )) CV_ERROR( CV_StsBadMask, "" ); if( !CV_ARE_SIZES_EQ( mat, matmask )) CV_ERROR( CV_StsUnmatchedSizes, "" ); mask_step = matmask->step; if( size.height == 1 ) mat_step = mask_step = CV_STUB_STEP; if( CV_MAT_CN(type) == 1 || coi == 0 ) { CvFunc2D_2A4P func = (CvFunc2D_2A4P)(minmaxmask_tab.fn_2d[depth]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, matmask->data.ptr, mask_step, size, &minVal, &maxVal, &minLoc, &maxLoc )); } else { CvFunc2DnC_2A4P func = (CvFunc2DnC_2A4P)(minmaxmaskcoi_tab.fn_2d[depth]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, matmask->data.ptr, mask_step, size, cn, coi, &minVal, &maxVal, &minLoc, &maxLoc )); } } if( depth < CV_32S || depth == CV_32F ) { minVal = *(float*)&minVal; maxVal = *(float*)&maxVal; } if( _minVal ) *_minVal = minVal; if( _maxVal ) *_maxVal = maxVal; if( _minLoc ) *_minLoc = minLoc; if( _maxLoc ) *_maxLoc = maxLoc; __END__; }
CV_IMPL int cvNamedWindow( const char* name, int flags ) { int result = 0; CV_FUNCNAME( "cvNamedWindow" ); __BEGIN__; HWND hWnd, mainhWnd; CvWindow* window; DWORD defStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU; int len; CvRect rect; cvInitSystem(0,0); if( !name ) CV_ERROR( CV_StsNullPtr, "NULL name string" ); // Check the name in the storage if( icvFindWindowByName( name ) != 0 ) { result = 1; EXIT; } if( (flags & CV_WINDOW_AUTOSIZE) == 0 ) defStyle |= WS_SIZEBOX; icvLoadWindowPos( name, rect ); mainhWnd = CreateWindow( "Main HighGUI class", name, defStyle | WS_OVERLAPPED, rect.x, rect.y, rect.width, rect.height, 0, 0, hg_hinstance, 0 ); if( !mainhWnd ) CV_ERROR( CV_StsError, "Frame window can not be created" ); ShowWindow(mainhWnd, SW_SHOW); hWnd = CreateWindow("HighGUI class", "", defStyle | WS_CHILD | WS_SIZEBOX, CW_USEDEFAULT, 0, rect.width, rect.height, mainhWnd, 0, hg_hinstance, 0); if( !hWnd ) CV_ERROR( CV_StsError, "Frame window can not be created" ); ShowWindow(hWnd, SW_SHOW); len = (int)strlen(name); CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); window->signature = CV_WINDOW_MAGIC_VAL; window->hwnd = hWnd; window->frame = mainhWnd; window->name = (char*)(window + 1); memcpy( window->name, name, len + 1 ); window->flags = flags; window->image = 0; window->dc = CreateCompatibleDC(0); window->last_key = 0; window->on_mouse = 0; window->on_mouse_param = 0; memset( &window->toolbar, 0, sizeof(window->toolbar)); window->next = hg_windows; window->prev = 0; if( hg_windows ) hg_windows->prev = window; hg_windows = window; icvSetWindowLongPtr( hWnd, CV_USERDATA, window ); icvSetWindowLongPtr( mainhWnd, CV_USERDATA, window ); // Recalculate window position icvUpdateWindowPos( window ); result = 1; __END__; return result; }
CV_IMPL void cvShowImage( const char* name, const CvArr* arr ) { CV_FUNCNAME( "cvShowImage" ); __BEGIN__; CvWindow* window; SIZE size = { 0, 0 }; int channels = 0; void* dst_ptr = 0; const int channels0 = 3; int origin = 0; CvMat stub, dst, *image; bool changed_size = false; // philipg if( !name ) CV_ERROR( CV_StsNullPtr, "NULL name" ); window = icvFindWindowByName(name); if(!window) { cvNamedWindow(name, 1); window = icvFindWindowByName(name); } if( !window || !arr ) EXIT; // keep silence here. if( CV_IS_IMAGE_HDR( arr )) origin = ((IplImage*)arr)->origin; CV_CALL( image = cvGetMat( arr, &stub )); if (window->image) // if there is something wrong with these system calls, we cannot display image... if (icvGetBitmapData( window, &size, &channels, &dst_ptr )) return; if( size.cx != image->width || size.cy != image->height || channels != channels0 ) { changed_size = true; uchar buffer[sizeof(BITMAPINFO) + 255*sizeof(RGBQUAD)]; BITMAPINFO* binfo = (BITMAPINFO*)buffer; DeleteObject( SelectObject( window->dc, window->image )); window->image = 0; size.cx = image->width; size.cy = image->height; channels = channels0; FillBitmapInfo( binfo, size.cx, size.cy, channels*8, 1 ); window->image = SelectObject( window->dc, CreateDIBSection(window->dc, binfo, DIB_RGB_COLORS, &dst_ptr, 0, 0)); } cvInitMatHeader( &dst, size.cy, size.cx, CV_8UC3, dst_ptr, (size.cx * channels + 3) & -4 ); cvConvertImage( image, &dst, origin == 0 ? CV_CVTIMG_FLIP : 0 ); // ony resize window if needed if (changed_size) icvUpdateWindowPos(window); InvalidateRect(window->hwnd, 0, 0); // philipg: this is not needed and just slows things down // UpdateWindow(window->hwnd); __END__; }
CV_IMPL int cvNamedWindow( const char* name, int flags ) { int result = 0; CV_FUNCNAME( "cvNamedWindow" ); __BEGIN__; CvWindow* window; int len; cvInitSystem(1,(char**)&name); if( !name ) CV_ERROR( CV_StsNullPtr, "NULL name string" ); // Check the name in the storage if( icvFindWindowByName( name ) != 0 ) { result = 1; EXIT; } len = strlen(name); CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); memset( window, 0, sizeof(*window)); window->name = (char*)(window + 1); memcpy( window->name, name, len + 1 ); window->flags = flags; window->signature = CV_WINDOW_MAGIC_VAL; window->last_key = 0; window->on_mouse = 0; window->on_mouse_param = 0; memset( &window->toolbar, 0, sizeof(window->toolbar)); window->next = hg_windows; window->prev = 0; window->status = CV_WINDOW_NORMAL;//YV CV_LOCK_MUTEX(); window->frame = gtk_window_new( GTK_WINDOW_TOPLEVEL ); window->paned = gtk_vbox_new( FALSE, 0 ); window->widget = cvImageWidgetNew( flags ); gtk_box_pack_end( GTK_BOX(window->paned), window->widget, TRUE, TRUE, 0 ); gtk_widget_show( window->widget ); gtk_container_add( GTK_CONTAINER(window->frame), window->paned ); gtk_widget_show( window->paned ); #ifndef HAVE_OPENGL if (flags & CV_WINDOW_OPENGL) CV_ERROR( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); #else if (flags & CV_WINDOW_OPENGL) createGlContext(window); window->glDrawCallback = 0; window->glDrawData = 0; #endif // // configure event handlers // TODO -- move this to CvImageWidget ? gtk_signal_connect( GTK_OBJECT(window->frame), "key-press-event", GTK_SIGNAL_FUNC(icvOnKeyPress), window ); gtk_signal_connect( GTK_OBJECT(window->widget), "button-press-event", GTK_SIGNAL_FUNC(icvOnMouse), window ); gtk_signal_connect( GTK_OBJECT(window->widget), "button-release-event", GTK_SIGNAL_FUNC(icvOnMouse), window ); gtk_signal_connect( GTK_OBJECT(window->widget), "motion-notify-event", GTK_SIGNAL_FUNC(icvOnMouse), window ); gtk_signal_connect( GTK_OBJECT(window->frame), "delete-event", GTK_SIGNAL_FUNC(icvOnClose), window ); gtk_signal_connect( GTK_OBJECT(window->widget), "expose-event", GTK_SIGNAL_FUNC(cvImageWidget_expose), window ); gtk_widget_add_events (window->widget, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK) ; gtk_widget_show( window->frame ); gtk_window_set_title( GTK_WINDOW(window->frame), name ); if( hg_windows ) hg_windows->prev = window; hg_windows = window; gtk_window_set_resizable( GTK_WINDOW(window->frame), (flags & CV_WINDOW_AUTOSIZE) == 0 ); // allow window to be resized if( (flags & CV_WINDOW_AUTOSIZE)==0 ){ GdkGeometry geometry; geometry.min_width = 50; geometry.min_height = 50; gtk_window_set_geometry_hints( GTK_WINDOW( window->frame ), GTK_WIDGET( window->widget ), &geometry, (GdkWindowHints) (GDK_HINT_MIN_SIZE)); } CV_UNLOCK_MUTEX(); #ifdef HAVE_OPENGL if (window->useGl) cvSetOpenGlContext(name); #endif result = 1; __END__; return result; }
int CvArrTest::prepare_test_case( int test_case_idx ) { int code = 1; CvSize** sizes = (CvSize**)malloc( max_arr*sizeof(sizes[0]) ); CvSize** whole_sizes = (CvSize**)malloc( max_arr*sizeof(whole_sizes[0]) ); int** types = (int**)malloc( max_arr*sizeof(types[0]) ); int i, j, total = 0; CvRNG* rng = ts->get_rng(); bool is_image = false; bool is_timing_test = false; CV_FUNCNAME( "CvArrTest::prepare_test_case" ); __BEGIN__; is_timing_test = ts->get_testing_mode() == CvTS::TIMING_MODE; if( is_timing_test ) { if( !get_next_timing_param_tuple() ) { code = -1; EXIT; } } for( i = 0; i < max_arr; i++ ) { int count = test_array[i].size(); count = MAX(count, 1); sizes[i] = (CvSize*)malloc( count*sizeof(sizes[i][0]) ); types[i] = (int*)malloc( count*sizeof(types[i][0]) ); whole_sizes[i] = (CvSize*)malloc( count*sizeof(whole_sizes[i][0]) ); } if( !is_timing_test ) get_test_array_types_and_sizes( test_case_idx, sizes, types ); else { get_timing_test_array_types_and_sizes( test_case_idx, sizes, types, whole_sizes, &is_image ); } for( i = 0; i < max_arr; i++ ) { int count = test_array[i].size(); total += count; for( j = 0; j < count; j++ ) { unsigned t = cvRandInt(rng); bool create_mask = true, use_roi = false; CvSize size = sizes[i][j], whole_size = size; CvRect roi = {0,0,0,0}; if( !is_timing_test ) { is_image = !cvmat_allowed ? true : iplimage_allowed ? (t & 1) != 0 : false; create_mask = (t & 6) == 0; // ~ each of 3 tests will use mask use_roi = (t & 8) != 0; if( use_roi ) { whole_size.width += cvRandInt(rng) % 10; whole_size.height += cvRandInt(rng) % 10; } } else { whole_size = whole_sizes[i][j]; use_roi = whole_size.width != size.width || whole_size.height != size.height; create_mask = cvReadInt(find_timing_param( "use_mask" ),0) != 0; } cvRelease( &test_array[i][j] ); if( size.width > 0 && size.height > 0 && types[i][j] >= 0 && (i != MASK || create_mask) ) { if( use_roi ) { roi.width = size.width; roi.height = size.height; if( whole_size.width > size.width ) { if( !is_timing_test ) roi.x = cvRandInt(rng) % (whole_size.width - size.width); else roi.x = 1; } if( whole_size.height > size.height ) { if( !is_timing_test ) roi.y = cvRandInt(rng) % (whole_size.height - size.height); else roi.y = 1; } } if( is_image ) { CV_CALL( test_array[i][j] = cvCreateImage( whole_size, icvTsTypeToDepth[CV_MAT_DEPTH(types[i][j])], CV_MAT_CN(types[i][j]) )); if( use_roi ) cvSetImageROI( (IplImage*)test_array[i][j], roi ); } else { CV_CALL( test_array[i][j] = cvCreateMat( whole_size.height, whole_size.width, types[i][j] )); if( use_roi ) { CvMat submat, *mat = (CvMat*)test_array[i][j]; cvGetSubRect( test_array[i][j], &submat, roi ); submat.refcount = mat->refcount; *mat = submat; } } } } } if( total > max_hdr ) { delete hdr; max_hdr = total; hdr = new CvMat[max_hdr]; } total = 0; for( i = 0; i < max_arr; i++ ) { int count = test_array[i].size(); test_mat[i] = count > 0 ? hdr + total : 0; for( j = 0; j < count; j++ ) { CvArr* arr = test_array[i][j]; CvMat* mat = &test_mat[i][j]; if( !arr ) memset( mat, 0, sizeof(*mat) ); else if( CV_IS_MAT( arr )) { *mat = *(CvMat*)arr; mat->refcount = 0; } else cvGetMat( arr, mat, 0, 0 ); if( mat->data.ptr ) fill_array( test_case_idx, i, j, mat ); } total += count; } __END__; for( i = 0; i < max_arr; i++ ) { if( sizes ) free( sizes[i] ); if( whole_sizes ) free( whole_sizes[i] ); if( types ) free( types[i] ); } free( sizes ); free( whole_sizes ); free( types ); return code; }
CV_IMPL void cvDecomposeProjectionMatrix( const CvMat *projMatr, CvMat *calibMatr, CvMat *rotMatr, CvMat *posVect, CvMat *rotMatrX, CvMat *rotMatrY, CvMat *rotMatrZ, CvPoint3D64f *eulerAngles) { CvMat *tmpProjMatr = 0; CvMat *tmpMatrixD = 0; CvMat *tmpMatrixV = 0; CvMat *tmpMatrixM = 0; CV_FUNCNAME("cvDecomposeProjectionMatrix"); __BEGIN__; /* Validate parameters. */ if(projMatr == 0 || calibMatr == 0 || rotMatr == 0 || posVect == 0) CV_ERROR(CV_StsNullPtr, "Some of parameters is a NULL pointer!"); if(!CV_IS_MAT(projMatr) || !CV_IS_MAT(calibMatr) || !CV_IS_MAT(rotMatr) || !CV_IS_MAT(posVect)) CV_ERROR(CV_StsUnsupportedFormat, "Input parameters must be a matrices!"); if(projMatr->cols != 4 || projMatr->rows != 3) CV_ERROR(CV_StsUnmatchedSizes, "Size of projection matrix must be 3x4!"); if(calibMatr->cols != 3 || calibMatr->rows != 3 || rotMatr->cols != 3 || rotMatr->rows != 3) CV_ERROR(CV_StsUnmatchedSizes, "Size of calibration and rotation matrices must be 3x3!"); if(posVect->cols != 1 || posVect->rows != 4) CV_ERROR(CV_StsUnmatchedSizes, "Size of position vector must be 4x1!"); CV_CALL(tmpProjMatr = cvCreateMat(4, 4, CV_64F)); CV_CALL(tmpMatrixD = cvCreateMat(4, 4, CV_64F)); CV_CALL(tmpMatrixV = cvCreateMat(4, 4, CV_64F)); CV_CALL(tmpMatrixM = cvCreateMat(3, 3, CV_64F)); /* Compute position vector. */ cvSetZero(tmpProjMatr); // Add zero row to make matrix square. int i, k; for(i = 0; i < 3; i++) for(k = 0; k < 4; k++) cvmSet(tmpProjMatr, i, k, cvmGet(projMatr, i, k)); CV_CALL(cvSVD(tmpProjMatr, tmpMatrixD, NULL, tmpMatrixV, CV_SVD_MODIFY_A + CV_SVD_V_T)); /* Save position vector. */ for(i = 0; i < 4; i++) cvmSet(posVect, i, 0, cvmGet(tmpMatrixV, 3, i)); // Solution is last row of V. /* Compute calibration and rotation matrices via RQ decomposition. */ cvGetCols(projMatr, tmpMatrixM, 0, 3); // M is first square matrix of P. assert(cvDet(tmpMatrixM) != 0.0); // So far only finite cameras could be decomposed, so M has to be nonsingular [det(M) != 0]. CV_CALL(cvRQDecomp3x3(tmpMatrixM, calibMatr, rotMatr, rotMatrX, rotMatrY, rotMatrZ, eulerAngles)); __END__; cvReleaseMat(&tmpProjMatr); cvReleaseMat(&tmpMatrixD); cvReleaseMat(&tmpMatrixV); cvReleaseMat(&tmpMatrixM); }
void icvGaussNewton( const CvMat* J, const CvMat* err, CvMat* delta, CvMat* JtJ, CvMat* JtErr, CvMat* JtJW, CvMat* JtJV ) { CvMat* _temp_JtJ = 0; CvMat* _temp_JtErr = 0; CvMat* _temp_JtJW = 0; CvMat* _temp_JtJV = 0; CV_FUNCNAME( "icvGaussNewton" ); __BEGIN__; if( !CV_IS_MAT(J) || !CV_IS_MAT(err) || !CV_IS_MAT(delta) ) CV_ERROR( CV_StsBadArg, "Some of required arguments is not a valid matrix" ); if( !JtJ ) { CV_CALL( _temp_JtJ = cvCreateMat( J->cols, J->cols, J->type )); JtJ = _temp_JtJ; } else if( !CV_IS_MAT(JtJ) ) CV_ERROR( CV_StsBadArg, "JtJ is not a valid matrix" ); if( !JtErr ) { CV_CALL( _temp_JtErr = cvCreateMat( J->cols, 1, J->type )); JtErr = _temp_JtErr; } else if( !CV_IS_MAT(JtErr) ) CV_ERROR( CV_StsBadArg, "JtErr is not a valid matrix" ); if( !JtJW ) { CV_CALL( _temp_JtJW = cvCreateMat( J->cols, 1, J->type )); JtJW = _temp_JtJW; } else if( !CV_IS_MAT(JtJW) ) CV_ERROR( CV_StsBadArg, "JtJW is not a valid matrix" ); if( !JtJV ) { CV_CALL( _temp_JtJV = cvCreateMat( J->cols, J->cols, J->type )); JtJV = _temp_JtJV; } else if( !CV_IS_MAT(JtJV) ) CV_ERROR( CV_StsBadArg, "JtJV is not a valid matrix" ); cvMulTransposed( J, JtJ, 1 ); cvGEMM( J, err, 1, 0, 0, JtErr, CV_GEMM_A_T ); cvSVD( JtJ, JtJW, 0, JtJV, CV_SVD_MODIFY_A + CV_SVD_V_T ); cvSVBkSb( JtJW, JtJV, JtJV, JtErr, delta, CV_SVD_U_T + CV_SVD_V_T ); __END__; if( _temp_JtJ || _temp_JtErr || _temp_JtJW || _temp_JtJV ) { cvReleaseMat( &_temp_JtJ ); cvReleaseMat( &_temp_JtErr ); cvReleaseMat( &_temp_JtJW ); cvReleaseMat( &_temp_JtJV ); } }
CV_IMPL void cvAbsDiffS( const void* srcarr, void* dstarr, CvScalar scalar ) { static CvFuncTable adiffs_tab; static int inittab = 0; CV_FUNCNAME( "cvAbsDiffS" ); __BEGIN__; int coi1 = 0, coi2 = 0; int type, sctype; CvMat srcstub, *src = (CvMat*)srcarr; CvMat dststub, *dst = (CvMat*)dstarr; int src_step = src->step; int dst_step = dst->step; double buf[12]; CvSize size; if( !inittab ) { icvInitAbsDiffCTable( &adiffs_tab ); inittab = 1; } CV_CALL( src = cvGetMat( src, &srcstub, &coi1 )); CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 )); if( coi1 != 0 || coi2 != 0 ) CV_ERROR( CV_BadCOI, "" ); if( !CV_ARE_TYPES_EQ(src, dst) ) CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); if( !CV_ARE_SIZES_EQ(src, dst) ) CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); sctype = type = CV_ARR_TYPE( src->type ); if( CV_ARR_DEPTH(type) < CV_32S ) sctype = (type & CV_ARR_CN_MASK) | CV_32SC1; size = icvGetMatSize( src ); size.width *= CV_ARR_CN( type ); src_step = src->step; dst_step = dst->step; if( CV_IS_ARR_CONT( src->type & dst->type )) { size.width *= size.height; size.height = 1; src_step = dst_step = CV_STUB_STEP; } CV_CALL( cvScalarToRawData( &scalar, sctype, buf, 1 )); { CvFunc2D_2A1P func = (CvFunc2D_2A1P) (adiffs_tab.fn_2d[CV_ARR_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); IPPI_CALL( func( src->data.ptr, src_step, dst->data.ptr, dst_step, size, buf )); } __END__; }
CV_IMPL int cvCountNonZero( const CvArr* arr ) { static CvFuncTable nz_tab; static CvFuncTable nzcoi_tab; static int inittab = 0; int count = 0; CV_FUNCNAME("cvCountNonZero"); __BEGIN__; int type, coi = 0; int mat_step; CvSize size; CvMat stub, *mat = (CvMat*)arr; if( !inittab ) { icvInitCountNonZeroC1RTable( &nz_tab ); icvInitCountNonZeroCnCRTable( &nzcoi_tab ); inittab = 1; } if( !CV_IS_MAT(mat) ) { if( CV_IS_MATND(mat) ) { void* matnd = (void*)arr; CvMatND nstub; CvNArrayIterator iterator; CvFunc2D_1A1P func; CV_CALL( cvInitNArrayIterator( 1, &matnd, 0, &nstub, &iterator )); type = CV_MAT_TYPE(iterator.hdr[0]->type); if( CV_MAT_CN(type) != 1 ) CV_ERROR( CV_BadNumChannels, "Only single-channel array are supported here" ); func = (CvFunc2D_1A1P)(nz_tab.fn_2d[CV_MAT_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsUnsupportedFormat, "" ); do { int temp; IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP, iterator.size, &temp )); count += temp; } while( cvNextNArraySlice( &iterator )); EXIT; } else CV_CALL( mat = cvGetMat( mat, &stub, &coi )); } type = CV_MAT_TYPE(mat->type); size = cvGetMatSize( mat ); mat_step = mat->step; if( CV_IS_MAT_CONT( mat->type )) { size.width *= size.height; size.height = 1; mat_step = CV_STUB_STEP; } if( CV_MAT_CN(type) == 1 || coi == 0 ) { CvFunc2D_1A1P func = (CvFunc2D_1A1P)(nz_tab.fn_2d[CV_MAT_DEPTH(type)]); if( CV_MAT_CN(type) != 1 ) CV_ERROR( CV_BadNumChannels, "The function can handle only a single channel at a time (use COI)"); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, &count )); } else { CvFunc2DnC_1A1P func = (CvFunc2DnC_1A1P)(nzcoi_tab.fn_2d[CV_MAT_DEPTH(type)]); if( !func ) CV_ERROR( CV_StsBadArg, cvUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, CV_MAT_CN(type), coi, &count )); } __END__; return count; }