CV_IMPL void cvCalcPGH( const CvSeq * contour, CvHistogram * hist ) { CV_FUNCNAME( "cvCalcPGH" ); __BEGIN__; 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] )); __END__; }
// ------------------------------------------------------------------------ void LABHistogram2D::Serialize( CArchive& ar ) { 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]; //// TEMP: //total = 30*30; float *ptr = 0; cvGetRawData( this->h->bins, (uchar**)&ptr); if (ar.IsStoring()) { for(int i = 0; i < total; i++ ) ar << ptr[i]; } else { for(int i = 0; i < total; i++ ) ar >> ptr[0]; } }
// ------------------------------------------------------------------------ System::String^ LABHistogram2D::ToString() { 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]; System::String ^s; float *ptr = 0; cvGetRawData( this->h->bins, (uchar**)&ptr); for(int i=0; i<a_bins;i++ ) { for(int j=0; j<b_bins;j++ ) { float bin_val = cvQueryHistValue_2D( h, i, j ); s += System::String::Format("{0:f4}, ", bin_val); } s += "\n"; } return s; }
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); }
// ------------------------------------------------------------------------ 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; }
static double icvGetThreshVal_Otsu( const CvHistogram* hist ) { double max_val = 0; CV_FUNCNAME( "icvGetThreshVal_Otsu" ); __BEGIN__; int i, count; const float* h; double sum = 0, mu = 0; bool uniform = false; double low = 0, high = 0, delta = 0; float* nu_thresh = 0; double mu1 = 0, q1 = 0; double max_sigma = 0; if( !CV_IS_HIST(hist) || CV_IS_SPARSE_HIST(hist) || hist->mat.dims != 1 ) CV_ERROR( CV_StsBadArg, "The histogram in Otsu method must be a valid dense 1D histogram" ); count = hist->mat.dim[0].size; h = (float*)cvPtr1D( hist->bins, 0 ); if( !CV_HIST_HAS_RANGES(hist) || CV_IS_UNIFORM_HIST(hist) ) { if( CV_HIST_HAS_RANGES(hist) ) { low = hist->thresh[0][0]; high = hist->thresh[0][1]; } else { low = 0; high = count; } delta = (high-low)/count; low += delta*0.5; uniform = true; } else nu_thresh = hist->thresh2[0]; for( i = 0; i < count; i++ ) { sum += h[i]; if( uniform ) mu += (i*delta + low)*h[i]; else mu += (nu_thresh[i*2] + nu_thresh[i*2+1])*0.5*h[i]; } sum = fabs(sum) > FLT_EPSILON ? 1./sum : 0; mu *= sum; mu1 = 0; q1 = 0; for( i = 0; i < count; i++ ) { double p_i, q2, mu2, val_i, sigma; p_i = h[i]*sum; mu1 *= q1; q1 += p_i; q2 = 1. - q1; if( MIN(q1,q2) < FLT_EPSILON || MAX(q1,q2) > 1. - FLT_EPSILON ) continue; if( uniform ) val_i = i*delta + low; else val_i = (nu_thresh[i*2] + nu_thresh[i*2+1])*0.5; mu1 = (mu1 + val_i*p_i)/q1; mu2 = (mu - q1*mu1)/q2; sigma = q1*q2*(mu1 - mu2)*(mu1 - mu2); if( sigma > max_sigma ) { max_sigma = sigma; max_val = val_i; } } __END__; return max_val; }