void test(CvMat* t) { //获取矩阵的数据类型 int type = cvGetElemType(t); CvHistogram //获取矩阵的维度信息 int size[10]; int dims = cvGetDims(t, size); int x = cvGetDimSize(t, 0); int y = cvGetDimSize(t, 1); }
double LABHistogram2D::Compare(const LABHistogram2D* that) { if( !CV_IS_HIST(h) || !CV_IS_HIST(that->h) ) ASSERT(false); int size1[CV_MAX_DIM], size2[CV_MAX_DIM]; int dims1 = cvGetDims( this->h->bins, size1 ); int dims2 = cvGetDims( that->h->bins, size2 ); int total = 1; if( dims1 != dims2 ) ASSERT(false); for(int i = 0; i < dims1; i++ ) { if( size1[i] != size2[i] ) ASSERT(false); total *= size1[i]; } float *ptr1 = 0, *ptr2 = 0; cvGetRawData( this->h->bins, (uchar**)&ptr1 ); cvGetRawData( that->h->bins, (uchar**)&ptr2 ); float sum = 0, sum1 = 0, sum2 = 0; for(int i = 0; i < total; i++ ) { float a = ptr1[i]; float b = ptr2[i]; sum += sqrt(a*b); sum1 += a; sum2 +=b; } // normalize both histograms so that all bins sum up to 1 if (sum1 == 0 || sum2 == 0) return 1; return sum/sqrt(sum1*sum2); }
static void cvTsCalcBackProjectPatch( IplImage** images, IplImage* dst, CvSize patch_size, CvHistogram* hist, int method, double factor, int* channels ) { CvHistogram* model = 0; IplImage imgstub[CV_MAX_DIM], *img[CV_MAX_DIM]; IplROI roi; int i, dims; int x, y; CvSize size = cvGetSize(dst); dims = cvGetDims( hist->bins ); cvCopyHist( hist, &model ); cvNormalizeHist( hist, factor ); cvZero( dst ); for( i = 0; i < dims; i++ ) { CvMat stub, *mat; mat = cvGetMat( images[i], &stub, 0, 0 ); img[i] = cvGetImage( mat, &imgstub[i] ); img[i]->roi = &roi; } roi.coi = 0; for( y = 0; y < size.height; y++ ) { for( x = 0; x < size.width; x++ ) { double result; roi.xOffset = x; roi.yOffset = y; roi.width = patch_size.width; roi.height = patch_size.height; cvTsCalcHist( img, model, 0, channels ); cvNormalizeHist( model, factor ); result = cvCompareHist( model, hist, method ); CV_IMAGE_ELEM( dst, float, y, x ) = (float)result; } } cvReleaseHist( &model ); }
// ------------------------------------------------------------------------ double LABHistogram2D::GetNorm() { if( !CV_IS_HIST(h)) ASSERT(false); int size[CV_MAX_DIM]; int dims = cvGetDims( this->h->bins, size ); int total = 1; for(int i = 0; i < dims; i++ ) total *= size[i]; float *ptr = 0; cvGetRawData( this->h->bins, (uchar**)&ptr); float sum = 0; for(int i = 0; i < total; i++ ) sum += ptr[i]; return sum; }
CV_IMPL void cvCalcPGH( const CvSeq * contour, CvHistogram * hist ) { int size[CV_MAX_DIM]; int dims; if( !CV_IS_HIST(hist)) CV_Error( CV_StsBadArg, "The histogram header is invalid " ); if( CV_IS_SPARSE_HIST( hist )) CV_Error( CV_StsUnsupportedFormat, "Sparse histogram are not supported" ); dims = cvGetDims( hist->bins, size ); if( dims != 2 ) CV_Error( CV_StsBadSize, "The histogram must be two-dimensional" ); if( !CV_IS_SEQ_POINT_SET( contour ) || CV_SEQ_ELTYPE( contour ) != CV_32SC2 ) CV_Error( CV_StsUnsupportedFormat, "The contour is not valid or the point type is not supported" ); IPPI_CALL( icvCalcPGH( contour, ((CvMatND*)(hist->bins))->data.fl, size[0], size[1] )); }
int get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets { return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; }
/* Warps source into destination by a perspective transform */ static 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; /* 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; ((uchar*)(dst_data + y * dst_step))[x] = (uchar) (i0 + (i1 - i0)*delta_y); } 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__; }
static void cvTsCalcBackProject( IplImage** images, IplImage* dst, CvHistogram* hist, int* channels ) { int x, y, k, cdims; union { float* fl; uchar* ptr; } plane[CV_MAX_DIM]; int nch[CV_MAX_DIM]; int dims[CV_MAX_DIM]; int uniform = CV_IS_UNIFORM_HIST(hist); CvSize img_size = cvGetSize(images[0]); int img_depth = images[0]->depth; cdims = cvGetDims( hist->bins, dims ); for( k = 0; k < cdims; k++ ) nch[k] = images[k]->nChannels; for( y = 0; y < img_size.height; y++ ) { if( img_depth == IPL_DEPTH_8U ) for( k = 0; k < cdims; k++ ) plane[k].ptr = &CV_IMAGE_ELEM(images[k], uchar, y, 0 ) + channels[k]; else for( k = 0; k < cdims; k++ ) plane[k].fl = &CV_IMAGE_ELEM(images[k], float, y, 0 ) + channels[k]; for( x = 0; x < img_size.width; x++ ) { float val[CV_MAX_DIM]; float bin_val = 0; int idx[CV_MAX_DIM]; if( img_depth == IPL_DEPTH_8U ) for( k = 0; k < cdims; k++ ) val[k] = plane[k].ptr[x*nch[k]]; else for( k = 0; k < cdims; k++ ) val[k] = plane[k].fl[x*nch[k]]; idx[cdims-1] = -1; if( uniform ) { for( k = 0; k < cdims; k++ ) { double v = val[k], lo = hist->thresh[k][0], hi = hist->thresh[k][1]; idx[k] = cvFloor((v - lo)*dims[k]/(hi - lo)); if( idx[k] < 0 || idx[k] >= dims[k] ) break; } } else { for( k = 0; k < cdims; k++ ) { float v = val[k]; float* t = hist->thresh2[k]; int j, n = dims[k]; for( j = 0; j <= n; j++ ) if( v < t[j] ) break; if( j <= 0 || j > n ) break; idx[k] = j-1; } } if( k == cdims ) bin_val = (float)cvGetRealND( hist->bins, idx ); if( img_depth == IPL_DEPTH_8U ) { int t = cvRound(bin_val); CV_IMAGE_ELEM( dst, uchar, y, x ) = CV_CAST_8U(t); } else CV_IMAGE_ELEM( dst, float, y, x ) = bin_val; } } }
static void cvTsCalcHist( IplImage** _images, CvHistogram* hist, IplImage* _mask, int* channels ) { int x, y, k, cdims; union { float* fl; uchar* ptr; } plane[CV_MAX_DIM]; int nch[CV_MAX_DIM]; int dims[CV_MAX_DIM]; int uniform = CV_IS_UNIFORM_HIST(hist); CvSize img_size = cvGetSize(_images[0]); CvMat images[CV_MAX_DIM], mask = cvMat(1,1,CV_8U); int img_depth = _images[0]->depth; cdims = cvGetDims( hist->bins, dims ); cvZero( hist->bins ); for( k = 0; k < cdims; k++ ) { cvGetMat( _images[k], &images[k] ); nch[k] = _images[k]->nChannels; } if( _mask ) cvGetMat( _mask, &mask ); for( y = 0; y < img_size.height; y++ ) { const uchar* mptr = _mask ? &CV_MAT_ELEM(mask, uchar, y, 0 ) : 0; if( img_depth == IPL_DEPTH_8U ) for( k = 0; k < cdims; k++ ) plane[k].ptr = &CV_MAT_ELEM(images[k], uchar, y, 0 ) + channels[k]; else for( k = 0; k < cdims; k++ ) plane[k].fl = &CV_MAT_ELEM(images[k], float, y, 0 ) + channels[k]; for( x = 0; x < img_size.width; x++ ) { float val[CV_MAX_DIM]; int idx[CV_MAX_DIM]; if( mptr && !mptr[x] ) continue; if( img_depth == IPL_DEPTH_8U ) for( k = 0; k < cdims; k++ ) val[k] = plane[k].ptr[x*nch[k]]; else for( k = 0; k < cdims; k++ ) val[k] = plane[k].fl[x*nch[k]]; idx[cdims-1] = -1; if( uniform ) { for( k = 0; k < cdims; k++ ) { double v = val[k], lo = hist->thresh[k][0], hi = hist->thresh[k][1]; idx[k] = cvFloor((v - lo)*dims[k]/(hi - lo)); if( idx[k] < 0 || idx[k] >= dims[k] ) break; } } else { for( k = 0; k < cdims; k++ ) { float v = val[k]; float* t = hist->thresh2[k]; int j, n = dims[k]; for( j = 0; j <= n; j++ ) if( v < t[j] ) break; if( j <= 0 || j > n ) break; idx[k] = j-1; } } if( k < cdims ) continue; (*(float*)cvPtrND( hist->bins, idx ))++; } } }