int CV_ThreshHistTest::validate_test_results( int /*test_case_idx*/ ) { int code = CvTS::OK; int i; float* ptr0 = values->data.fl; float* ptr = 0; CvSparseMat* sparse = 0; if( hist_type == CV_HIST_ARRAY ) ptr = (float*)cvPtr1D( hist[0]->bins, 0 ); else sparse = (CvSparseMat*)hist[0]->bins; if( code > 0 ) { for( i = 0; i < orig_nz_count; i++ ) { float v0 = ptr0[i], v; if( hist_type == CV_HIST_ARRAY ) v = ptr[i]; else { v = (float)cvGetRealND( sparse, indices->data.i + i*cdims ); cvClearND( sparse, indices->data.i + i*cdims ); } if( v0 <= threshold ) v0 = 0.f; if( cvIsNaN(v) || cvIsInf(v) ) { ts->printf( CvTS::LOG, "The %d-th bin is invalid (=%g)\n", i, v ); code = CvTS::FAIL_INVALID_OUTPUT; break; } else if( fabs(v0 - v) > FLT_EPSILON*10*fabs(v0) ) { ts->printf( CvTS::LOG, "The %d-th bin is incorrect (=%g, should be =%g)\n", i, v, v0 ); code = CvTS::FAIL_BAD_ACCURACY; break; } } } if( code > 0 && hist_type == CV_HIST_SPARSE ) { if( sparse->heap->active_count > 0 ) { ts->printf( CvTS::LOG, "There some extra histogram bins in the sparse histogram after the thresholding\n" ); code = CvTS::FAIL_INVALID_OUTPUT; } } if( code < 0 ) ts->set_failed_test_info( code ); return code; }
float query( int* bin ) const { return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; }
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; } } }
void CV_QueryHistTest::run_func(void) { int i, iters = values->cols; CvArr* h = hist[0]->bins; const int* idx = indices->data.i; float* val = values->data.fl; float default_value = 0.f; // stage 1: write bins if( cdims == 1 ) for( i = 0; i < iters; i++ ) { float v0 = values0->data.fl[i]; if( fabs(v0 - default_value) < FLT_EPSILON ) continue; if( !(i % 2) ) { if( !(i % 4) ) cvSetReal1D( h, idx[i], v0 ); else *(float*)cvPtr1D( h, idx[i] ) = v0; } else cvSetRealND( h, idx+i, v0 ); } else if( cdims == 2 ) for( i = 0; i < iters; i++ ) { float v0 = values0->data.fl[i]; if( fabs(v0 - default_value) < FLT_EPSILON ) continue; if( !(i % 2) ) { if( !(i % 4) ) cvSetReal2D( h, idx[i*2], idx[i*2+1], v0 ); else *(float*)cvPtr2D( h, idx[i*2], idx[i*2+1] ) = v0; } else cvSetRealND( h, idx+i*2, v0 ); } else if( cdims == 3 ) for( i = 0; i < iters; i++ ) { float v0 = values0->data.fl[i]; if( fabs(v0 - default_value) < FLT_EPSILON ) continue; if( !(i % 2) ) { if( !(i % 4) ) cvSetReal3D( h, idx[i*3], idx[i*3+1], idx[i*3+2], v0 ); else *(float*)cvPtr3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] ) = v0; } else cvSetRealND( h, idx+i*3, v0 ); } else for( i = 0; i < iters; i++ ) { float v0 = values0->data.fl[i]; if( fabs(v0 - default_value) < FLT_EPSILON ) continue; if( !(i % 2) ) cvSetRealND( h, idx+i*cdims, v0 ); else *(float*)cvPtrND( h, idx+i*cdims ) = v0; } // stage 2: read bins if( cdims == 1 ) for( i = 0; i < iters; i++ ) { if( !(i % 2) ) val[i] = *(float*)cvPtr1D( h, idx[i] ); else val[i] = (float)cvGetReal1D( h, idx[i] ); } else if( cdims == 2 ) for( i = 0; i < iters; i++ ) { if( !(i % 2) ) val[i] = *(float*)cvPtr2D( h, idx[i*2], idx[i*2+1] ); else val[i] = (float)cvGetReal2D( h, idx[i*2], idx[i*2+1] ); } else if( cdims == 3 ) for( i = 0; i < iters; i++ ) { if( !(i % 2) ) val[i] = *(float*)cvPtr3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] ); else val[i] = (float)cvGetReal3D( h, idx[i*3], idx[i*3+1], idx[i*3+2] ); } else for( i = 0; i < iters; i++ ) { if( !(i % 2) ) val[i] = *(float*)cvPtrND( h, idx+i*cdims ); else val[i] = (float)cvGetRealND( h, idx+i*cdims ); } }
int CV_CompareHistTest::validate_test_results( int /*test_case_idx*/ ) { int code = CvTS::OK; int i; double result0[MAX_METHOD+1]; double s0 = 0, s1 = 0, sq0 = 0, sq1 = 0, t; for( i = 0; i < MAX_METHOD; i++ ) result0[i] = 0; if( hist_type == CV_HIST_ARRAY ) { float* ptr0 = (float*)cvPtr1D( hist[0]->bins, 0 ); float* ptr1 = (float*)cvPtr1D( hist[1]->bins, 0 ); for( i = 0; i < total_size; i++ ) { double v0 = ptr0[i], v1 = ptr1[i]; result0[CV_COMP_CORREL] += v0*v1; result0[CV_COMP_INTERSECT] += MIN(v0,v1); if( fabs(v0 + v1) > DBL_EPSILON ) result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/(v0 + v1); s0 += v0; s1 += v1; sq0 += v0*v0; sq1 += v1*v1; result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1); } } else { CvSparseMat* sparse0 = (CvSparseMat*)hist[0]->bins; CvSparseMat* sparse1 = (CvSparseMat*)hist[1]->bins; CvSparseMatIterator iterator; CvSparseNode* node; for( node = cvInitSparseMatIterator( sparse0, &iterator ); node != 0; node = cvGetNextSparseNode( &iterator ) ) { const int* idx = CV_NODE_IDX(sparse0, node); double v0 = *(float*)CV_NODE_VAL(sparse0, node); double v1 = (float)cvGetRealND(sparse1, idx); result0[CV_COMP_CORREL] += v0*v1; result0[CV_COMP_INTERSECT] += MIN(v0,v1); if( fabs(v0 + v1) > DBL_EPSILON ) result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/(v0 + v1); s0 += v0; sq0 += v0*v0; result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1); } for( node = cvInitSparseMatIterator( sparse1, &iterator ); node != 0; node = cvGetNextSparseNode( &iterator ) ) { const int* idx = CV_NODE_IDX(sparse1, node); double v1 = *(float*)CV_NODE_VAL(sparse1, node); double v0 = (float)cvGetRealND(sparse0, idx); if( fabs(v0) < DBL_EPSILON ) result0[CV_COMP_CHISQR] += v1; s1 += v1; sq1 += v1*v1; } } t = (sq0 - s0*s0/total_size)*(sq1 - s1*s1/total_size); result0[CV_COMP_CORREL] = fabs(t) > DBL_EPSILON ? (result0[CV_COMP_CORREL] - s0*s1/total_size)/sqrt(t) : 1; s1 *= s0; s0 = result0[CV_COMP_BHATTACHARYYA]; s0 = 1. - s0*(s1 > FLT_EPSILON ? 1./sqrt(s1) : 1.); result0[CV_COMP_BHATTACHARYYA] = sqrt(MAX(s0,0.)); for( i = 0; i < MAX_METHOD; i++ ) { double v = result[i], v0 = result0[i]; const char* method_name = i == CV_COMP_CHISQR ? "Chi-Square" : i == CV_COMP_CORREL ? "Correlation" : i == CV_COMP_INTERSECT ? "Intersection" : i == CV_COMP_BHATTACHARYYA ? "Bhattacharyya" : "Unknown"; if( cvIsNaN(v) || cvIsInf(v) ) { ts->printf( CvTS::LOG, "The comparison result using the method #%d (%s) is invalid (=%g)\n", i, method_name, v ); code = CvTS::FAIL_INVALID_OUTPUT; break; } else if( fabs(v0 - v) > FLT_EPSILON*10*MAX(fabs(v0),0.1) ) { ts->printf( CvTS::LOG, "The comparison result using the method #%d (%s)\n\tis inaccurate (=%g, should be =%g)\n", i, method_name, v, v0 ); code = CvTS::FAIL_BAD_ACCURACY; break; } } if( code < 0 ) ts->set_failed_test_info( code ); return code; }