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 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; }
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 ))++; } } }