CvSeq * MBLBPDetectMultiScale( const IplImage* img, MBLBPCascade * pCascade, CvMemStorage* storage, int scale_factor1024x, int min_neighbors, int min_size, int max_size) { IplImage stub; CvMat mat, *pmat; CvSeq* seq = 0; CvSeq* seq2 = 0; CvSeq* idx_seq = 0; CvSeq* result_seq = 0; CvSeq* positions = 0; CvMemStorage* temp_storage = 0; CvAvgComp* comps = 0; CV_FUNCNAME( "MBLBPDetectMultiScale" ); __BEGIN__; int factor1024x; int factor1024x_max; int coi; if( ! pCascade) CV_ERROR( CV_StsNullPtr, "Invalid classifier cascade" ); if( !storage ) CV_ERROR( CV_StsNullPtr, "Null storage pointer" ); CV_CALL( img = cvGetImage( img, &stub)); CV_CALL( pmat = cvGetMat( img, &mat, &coi)); if( coi ) CV_ERROR( CV_BadCOI, "COI is not supported" ); if( CV_MAT_DEPTH(pmat->type) != CV_8U ) CV_ERROR( CV_StsUnsupportedFormat, "Only 8-bit images are supported" ); if( CV_MAT_CN(pmat->type) > 1 ) CV_ERROR( CV_StsUnsupportedFormat, "Only single-channel images are supported" ); min_size = MAX(pCascade->win_width, min_size); if(max_size <=0 ) max_size = MIN(img->width, img->height); if(max_size < min_size) return NULL; CV_CALL( temp_storage = cvCreateChildMemStorage( storage )); seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvRect), temp_storage ); seq2 = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), temp_storage ); result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), storage ); positions = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), temp_storage ); if( min_neighbors == 0 ) seq = result_seq; factor1024x = ((min_size<<10)+(pCascade->win_width/2)) / pCascade->win_width; factor1024x_max = (max_size<<10) / pCascade->win_width; //do not round it, to avoid the scan window be out of range #ifdef _OPENMP omp_init_lock(&lock); #endif for( ; factor1024x <= factor1024x_max; factor1024x = ((factor1024x*scale_factor1024x+512)>>10) ) { IplImage * pSmallImage = cvCreateImage( cvSize( ((img->width<<10)+factor1024x/2)/factor1024x, ((img->height<<10)+factor1024x/2)/factor1024x), IPL_DEPTH_8U, 1); try{ cvResize(img, pSmallImage); } catch(...) { cvReleaseImage(&pSmallImage); return NULL; } CvSize winStride = cvSize( (factor1024x<=2048)+1, (factor1024x<=2048)+1 ); cvClearSeq(positions); MBLBPDetectSingleScale( pSmallImage, pCascade, positions, winStride); for(int i=0; i < (positions ? positions->total : 0); i++) { CvPoint pt = *(CvPoint*)cvGetSeqElem( positions, i ); CvRect r = cvRect( (pt.x * factor1024x + 512)>>10, (pt.y * factor1024x + 512)>>10, (pCascade->win_width * factor1024x + 512)>>10, (pCascade->win_height * factor1024x + 512)>>10); cvSeqPush(seq, &r); } cvReleaseImage(&pSmallImage); } #ifdef _OPENMP omp_destroy_lock(&lock); #endif if( min_neighbors != 0 ) { // group retrieved rectangles in order to filter out noise int ncomp = cvSeqPartition( seq, 0, &idx_seq, (CvCmpFunc)is_equal, 0 ); CV_CALL( comps = (CvAvgComp*)cvAlloc( (ncomp+1)*sizeof(comps[0]))); memset( comps, 0, (ncomp+1)*sizeof(comps[0])); // count number of neighbors for(int i = 0; i < seq->total; i++ ) { CvRect r1 = *(CvRect*)cvGetSeqElem( seq, i ); int idx = *(int*)cvGetSeqElem( idx_seq, i ); assert( (unsigned)idx < (unsigned)ncomp ); comps[idx].neighbors++; comps[idx].rect.x += r1.x; comps[idx].rect.y += r1.y; comps[idx].rect.width += r1.width; comps[idx].rect.height += r1.height; } // calculate average bounding box for(int i = 0; i < ncomp; i++ ) { int n = comps[i].neighbors; if( n >= min_neighbors ) { CvAvgComp comp; comp.rect.x = (comps[i].rect.x*2 + n)/(2*n); comp.rect.y = (comps[i].rect.y*2 + n)/(2*n); comp.rect.width = (comps[i].rect.width*2 + n)/(2*n); comp.rect.height = (comps[i].rect.height*2 + n)/(2*n); comp.neighbors = comps[i].neighbors; cvSeqPush( seq2, &comp ); } } // filter out small face rectangles inside large face rectangles for(int i = 0; i < seq2->total; i++ ) { CvAvgComp r1 = *(CvAvgComp*)cvGetSeqElem( seq2, i ); int j, flag = 1; for( j = 0; j < seq2->total; j++ ) { CvAvgComp r2 = *(CvAvgComp*)cvGetSeqElem( seq2, j ); int distance = (r2.rect.width *2+5)/10;//cvRound( r2.rect.width * 0.2 ); if( i != j && r1.rect.x >= r2.rect.x - distance && r1.rect.y >= r2.rect.y - distance && r1.rect.x + r1.rect.width <= r2.rect.x + r2.rect.width + distance && r1.rect.y + r1.rect.height <= r2.rect.y + r2.rect.height + distance && (r2.neighbors > MAX( 3, r1.neighbors ) || r1.neighbors < 3) ) { flag = 0; break; } } if( flag ) { cvSeqPush( result_seq, &r1 ); /* cvSeqPush( result_seq, &r1.rect ); */ } } } __END__; cvReleaseMemStorage( &temp_storage ); cvFree( &comps ); return result_seq; }
/* Warps source into destination by a perspective transform */ void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] ) { CV_FUNCNAME( "cvWarpPerspective" ); __BEGIN__; #ifdef __IPL_H__ IplImage src_stub, dst_stub; IplImage* src_img; IplImage* dst_img; CV_CALL( src_img = cvGetImage( src, &src_stub ) ); CV_CALL( dst_img = cvGetImage( dst, &dst_stub ) ); iplWarpPerspectiveQ( src_img, dst_img, quad, IPL_WARP_R_TO_Q, IPL_INTER_CUBIC | IPL_SMOOTH_EDGE ); #else int fill_value = 0; double c[3][3]; /* transformation coefficients */ double q[4][2]; /* rearranged quad */ int left = 0; int right = 0; int next_right = 0; int next_left = 0; double y_min = 0; double y_max = 0; double k_left, b_left, k_right, b_right; uchar* src_data; int src_step; CvSize src_size; uchar* dst_data; int dst_step; CvSize dst_size; double d = 0; int direction = 0; int i; if( !src || (!CV_IS_IMAGE( src ) && !CV_IS_MAT( src )) || cvGetElemType( src ) != CV_8UC1 || cvGetDims( src ) != 2 ) { CV_ERROR( CV_StsBadArg, "Source must be two-dimensional array of CV_8UC1 type." ); } if( !dst || (!CV_IS_IMAGE( dst ) && !CV_IS_MAT( dst )) || cvGetElemType( dst ) != CV_8UC1 || cvGetDims( dst ) != 2 ) { CV_ERROR( CV_StsBadArg, "Destination must be two-dimensional array of CV_8UC1 type." ); } CV_CALL( cvGetRawData( src, &src_data, &src_step, &src_size ) ); CV_CALL( cvGetRawData( dst, &dst_data, &dst_step, &dst_size ) ); CV_CALL( cvGetPerspectiveTransform( src_size, quad, c ) ); /* if direction > 0 then vertices in quad follow in a CW direction, otherwise they follow in a CCW direction */ direction = 0; for( i = 0; i < 4; ++i ) { int ni = i + 1; if( ni == 4 ) ni = 0; int pi = i - 1; if( pi == -1 ) pi = 3; d = (quad[i][0] - quad[pi][0])*(quad[ni][1] - quad[i][1]) - (quad[i][1] - quad[pi][1])*(quad[ni][0] - quad[i][0]); int cur_direction = CV_SIGN(d); if( direction == 0 ) { direction = cur_direction; } else if( direction * cur_direction < 0 ) { direction = 0; break; } } if( direction == 0 ) { CV_ERROR( CV_StsBadArg, "Quadrangle is nonconvex or degenerated." ); } /* <left> is the index of the topmost quad vertice if there are two such vertices <left> is the leftmost one */ left = 0; for( i = 1; i < 4; ++i ) { if( (quad[i][1] < quad[left][1]) || ((quad[i][1] == quad[left][1]) && (quad[i][0] < quad[left][0])) ) { left = i; } } /* rearrange <quad> vertices in such way that they follow in a CW direction and the first vertice is the topmost one and put them into <q> */ if( direction > 0 ) { for( i = left; i < 4; ++i ) { q[i-left][0] = quad[i][0]; q[i-left][1] = quad[i][1]; } for( i = 0; i < left; ++i ) { q[4-left+i][0] = quad[i][0]; q[4-left+i][1] = quad[i][1]; } } else { for( i = left; i >= 0; --i ) { q[left-i][0] = quad[i][0]; q[left-i][1] = quad[i][1]; } for( i = 3; i > left; --i ) { q[4+left-i][0] = quad[i][0]; q[4+left-i][1] = quad[i][1]; } } left = right = 0; /* if there are two topmost points, <right> is the index of the rightmost one otherwise <right> */ if( q[left][1] == q[left+1][1] ) { right = 1; } /* <next_left> follows <left> in a CCW direction */ next_left = 3; /* <next_right> follows <right> in a CW direction */ next_right = right + 1; /* subtraction of 1 prevents skipping of the first row */ y_min = q[left][1] - 1; /* left edge equation: y = k_left * x + b_left */ k_left = (q[left][0] - q[next_left][0]) / (q[left][1] - q[next_left][1]); b_left = (q[left][1] * q[next_left][0] - q[left][0] * q[next_left][1]) / (q[left][1] - q[next_left][1]); /* right edge equation: y = k_right * x + b_right */ k_right = (q[right][0] - q[next_right][0]) / (q[right][1] - q[next_right][1]); b_right = (q[right][1] * q[next_right][0] - q[right][0] * q[next_right][1]) / (q[right][1] - q[next_right][1]); for(;;) { int x, y; y_max = MIN( q[next_left][1], q[next_right][1] ); int iy_min = MAX( cvRound(y_min), 0 ) + 1; int iy_max = MIN( cvRound(y_max), dst_size.height - 1 ); double x_min = k_left * iy_min + b_left; double x_max = k_right * iy_min + b_right; /* walk through the destination quadrangle row by row */ for( y = iy_min; y <= iy_max; ++y ) { int ix_min = MAX( cvRound( x_min ), 0 ); int ix_max = MIN( cvRound( x_max ), dst_size.width - 1 ); for( x = ix_min; x <= ix_max; ++x ) { /* calculate coordinates of the corresponding source array point */ double div = (c[2][0] * x + c[2][1] * y + c[2][2]); double src_x = (c[0][0] * x + c[0][1] * y + c[0][2]) / div; double src_y = (c[1][0] * x + c[1][1] * y + c[1][2]) / div; int isrc_x = cvFloor( src_x ); int isrc_y = cvFloor( src_y ); double delta_x = src_x - isrc_x; double delta_y = src_y - isrc_y; uchar* s = src_data + isrc_y * src_step + isrc_x; int i00, i10, i01, i11; i00 = i10 = i01 = i11 = (int) fill_value; double i = fill_value; /* linear interpolation using 2x2 neighborhood */ if( isrc_x >= 0 && isrc_x <= src_size.width && isrc_y >= 0 && isrc_y <= src_size.height ) { i00 = s[0]; } if( isrc_x >= -1 && isrc_x < src_size.width && isrc_y >= 0 && isrc_y <= src_size.height ) { i10 = s[1]; } if( isrc_x >= 0 && isrc_x <= src_size.width && isrc_y >= -1 && isrc_y < src_size.height ) { i01 = s[src_step]; } if( isrc_x >= -1 && isrc_x < src_size.width && isrc_y >= -1 && isrc_y < src_size.height ) { i11 = s[src_step+1]; } double i0 = i00 + (i10 - i00)*delta_x; double i1 = i01 + (i11 - i01)*delta_x; i = i0 + (i1 - i0)*delta_y; ((uchar*)(dst_data + y * dst_step))[x] = (uchar) i; } x_min += k_left; x_max += k_right; } if( (next_left == next_right) || (next_left+1 == next_right && q[next_left][1] == q[next_right][1]) ) { break; } if( y_max == q[next_left][1] ) { left = next_left; next_left = left - 1; k_left = (q[left][0] - q[next_left][0]) / (q[left][1] - q[next_left][1]); b_left = (q[left][1] * q[next_left][0] - q[left][0] * q[next_left][1]) / (q[left][1] - q[next_left][1]); } if( y_max == q[next_right][1] ) { right = next_right; next_right = right + 1; k_right = (q[right][0] - q[next_right][0]) / (q[right][1] - q[next_right][1]); b_right = (q[right][1] * q[next_right][0] - q[right][0] * q[next_right][1]) / (q[right][1] - q[next_right][1]); } y_min = y_max; } #endif /* #ifndef __IPL_H__ */ __END__; }
void IplTexture::setImage(CvMat *mat) { setImage(cvGetImage(mat, &header)); }
void cv_jit_calibration_findcorners(t_cv_jit_calibration *x, t_jit_matrix_info in_minfo, t_jit_matrix_info out_minfo, void *in_matrix, void *out_matrix, CvMat in_cv, char *out_bp ){ int board_point_nb = x->pattern_size[0]*x->pattern_size[1]; CvPoint2D32f *corners = new CvPoint2D32f[board_point_nb]; int corner_count; int step; CvSize pattern_size, image_size; IplImage *gray_image, *color_image, in_image; //in_image = cvCreateImageHeader(cvSize(in_minfo.dim[0], in_minfo.dim[1]), 8, in_minfo.planecount); if ( x->pattern_size[0] < 3 || x->pattern_size[1] < 3 ) { jit_object_error((t_object *) x, "pattern_size must be at least 3 x 3"); return; } pattern_size = cvSize( x->pattern_size[0], x->pattern_size[1] ); image_size = cvSize(in_minfo.dim[0], in_minfo.dim[1]); cvGetImage (&in_cv, &in_image); // create an IplImage from a CvMat // Here we create 2 copies of input matrix, a color and a grayscale // This is to avoid modifying the original // and also to deal with different kind of images supported by the following functions color_image = cvCreateImage(image_size, 8, 4); gray_image = cvCreateImage(image_size, 8, 1); // convert image colorspace if ( in_minfo.planecount == 1 ) { cvCvtColor(&in_image, color_image, CV_GRAY2RGBA); memcpy(gray_image->imageData, in_image.imageData, in_image.imageSize); } else { cvCvtColor(&in_image, gray_image, CV_RGBA2GRAY); memcpy(color_image->imageData, in_image.imageData, in_image.imageSize); } // find chessboard corners (grayscale or color image) int found = cvFindChessboardCorners(&in_cv, pattern_size, corners, &corner_count, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS); // get subpixel accuracy on those corners (grayscale image only) cvFindCornerSubPix(gray_image, corners, corner_count, cvSize(11,11), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1)); // draw chessboard corner (color image only) cvDrawChessboardCorners(color_image, pattern_size, corners, corner_count, found); x->frame++; if ( x->frame % x->wait_n_frame == 0 ) { // update arrays if( corner_count == board_point_nb ) { step = x->success_count*board_point_nb; for( int i=step, j=0; j<board_point_nb; ++i,++j ) { CV_MAT_ELEM(*x->image_points, float,i,0) = corners[j].x; CV_MAT_ELEM(*x->image_points, float,i,1) = corners[j].y; CV_MAT_ELEM(*x->object_points,float,i,0) = j/x->pattern_size[0]; CV_MAT_ELEM(*x->object_points,float,i,1) = j%x->pattern_size[0]; CV_MAT_ELEM(*x->object_points,float,i,2) = 0.0f; } CV_MAT_ELEM(*x->point_counts, int,x->success_count,0) = board_point_nb; x->success_count++; // invert view cvNot( color_image , color_image ); } }
bool CvCalibFilter::Rectify( CvMat** srcarr, CvMat** dstarr ) { int i; if( !srcarr || !dstarr ) { assert(0); return false; } if( isCalibrated && cameraCount == 2 ) { for( i = 0; i < cameraCount; i++ ) { if( srcarr[i] && dstarr[i] ) { IplImage src_stub, *src; IplImage dst_stub, *dst; src = cvGetImage( srcarr[i], &src_stub ); dst = cvGetImage( dstarr[i], &dst_stub ); if( src->imageData == dst->imageData ) { if( !undistImg || undistImg->width != src->width || undistImg->height != src->height || CV_MAT_CN(undistImg->type) != src->nChannels ) { cvReleaseMat( &undistImg ); undistImg = cvCreateMat( src->height, src->width, CV_8U + (src->nChannels-1)*8 ); } cvCopy( src, undistImg ); src = cvGetImage( undistImg, &src_stub ); } cvZero( dst ); if( !rectMap[i][0] || rectMap[i][0]->width != src->width || rectMap[i][0]->height != src->height ) { cvReleaseMat( &rectMap[i][0] ); cvReleaseMat( &rectMap[i][1] ); rectMap[i][0] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1); rectMap[i][1] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1); cvComputePerspectiveMap(stereo.coeffs[i], rectMap[i][0], rectMap[i][1]); } cvRemap( src, dst, rectMap[i][0], rectMap[i][1] ); } } } else { for( i = 0; i < cameraCount; i++ ) { if( srcarr[i] != dstarr[i] ) cvCopy( srcarr[i], dstarr[i] ); } } return true; }