int CV_QueryHistTest::validate_test_results( int /*test_case_idx*/ ) { int code = CvTS::OK; int i, j, iters = values->cols; for( i = 0; i < iters; i++ ) { float v = values->data.fl[i], v0 = values0->data.fl[i]; if( cvIsNaN(v) || cvIsInf(v) ) { ts->printf( CvTS::LOG, "The bin #%d has invalid value\n", i ); code = CvTS::FAIL_INVALID_OUTPUT; } else if( fabs(v - v0) > FLT_EPSILON ) { ts->printf( CvTS::LOG, "The bin #%d = %g, while it should be %g\n", i, v, v0 ); code = CvTS::FAIL_BAD_ACCURACY; } if( code < 0 ) { ts->printf( CvTS::LOG, "The bin index = (" ); for( j = 0; j < cdims; j++ ) ts->printf( CvTS::LOG, "%d%s", indices->data.i[i*cdims + j], j < cdims-1 ? ", " : ")\n" ); break; } } if( code < 0 ) ts->set_failed_test_info( code ); return code; }
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; }
int CV_MinMaxHistTest::validate_test_results( int /*test_case_idx*/ ) { int code = CvTS::OK; if( cvIsNaN(min_val) || cvIsInf(min_val) || cvIsNaN(max_val) || cvIsInf(max_val) ) { ts->printf( CvTS::LOG, "The extrema histogram bin values are invalid (min = %g, max = %g)\n", min_val, max_val ); code = CvTS::FAIL_INVALID_OUTPUT; } else if( fabs(min_val - min_val0) > FLT_EPSILON || fabs(max_val - max_val0) > FLT_EPSILON ) { ts->printf( CvTS::LOG, "The extrema histogram bin values are incorrect: (min = %g, should be = %g), (max = %g, should be = %g)\n", min_val, min_val0, max_val, max_val0 ); code = CvTS::FAIL_BAD_ACCURACY; } else { int i; for( i = 0; i < cdims; i++ ) { if( min_idx[i] != min_idx0[i] || max_idx[i] != max_idx0[i] ) { ts->printf( CvTS::LOG, "The %d-th coordinates of extrema histogram bin values are incorrect: " "(min = %d, should be = %d), (max = %d, should be = %d)\n", i, min_idx[i], min_idx0[i], max_idx[i], max_idx0[i] ); code = CvTS::FAIL_BAD_ACCURACY; } } } if( code < 0 ) ts->set_failed_test_info( code ); return code; }
/* * call-seq: * angle -> float * * Return angle. */ VALUE rb_angle(VALUE self) { CvMoments *moments = CVMOMENTS(self); double m11 = cvGetCentralMoment(moments, 1, 1), m20 = cvGetCentralMoment(moments, 2, 0), m02 = cvGetCentralMoment(moments, 0, 2), mangle = 0.5 * atan(2 * m11 / (m20 - m02)); if(cvIsNaN(mangle) || cvIsInf(mangle)) return Qnil; else return rb_float_new(mangle); }
int CV_BayesianProbTest::validate_test_results( int /*test_case_idx*/ ) { int code = CvTS::OK; int i, j, n = hist_count/2; double s[CV_MAX_DIM]; const double err_level = 1e-5; for( i = 0; i < total_size; i++ ) { double sum = 0; for( j = 0; j < n; j++ ) { double v = hist[j]->mat.data.fl[i]; sum += v; s[j] = v; } sum = sum > DBL_EPSILON ? 1./sum : 0; for( j = 0; j < n; j++ ) { double v0 = s[j]*sum; double v = hist[j+n]->mat.data.fl[i]; if( cvIsNaN(v) || cvIsInf(v) ) { ts->printf( CvTS::LOG, "The element #%d in the destination histogram #%d is invalid (=%g)\n", i, j, v ); code = CvTS::FAIL_INVALID_OUTPUT; break; } else if( fabs(v0 - v) > err_level*fabs(v0) ) { ts->printf( CvTS::LOG, "The element #%d in the destination histogram #%d is inaccurate (=%g, should be =%g)\n", i, j, v, v0 ); code = CvTS::FAIL_BAD_ACCURACY; break; } } if( j < n ) break; } if( code < 0 ) ts->set_failed_test_info( code ); return code; }
int CV_NormHistTest::validate_test_results( int /*test_case_idx*/ ) { int code = CvTS::OK; double sum = 0; if( hist_type == CV_HIST_ARRAY ) { int i; const float* ptr = (float*)cvPtr1D( hist[0]->bins, 0 ); for( i = 0; i < total_size; i++ ) sum += ptr[i]; } else { CvSparseMat* sparse = (CvSparseMat*)hist[0]->bins; CvSparseMatIterator iterator; CvSparseNode *node; for( node = cvInitSparseMatIterator( sparse, &iterator ); node != 0; node = cvGetNextSparseNode( &iterator )) { sum += *(float*)CV_NODE_VAL(sparse,node); } } if( cvIsNaN(sum) || cvIsInf(sum) ) { ts->printf( CvTS::LOG, "The normalized histogram has invalid sum =%g\n", sum ); code = CvTS::FAIL_INVALID_OUTPUT; } else if( fabs(sum - factor) > FLT_EPSILON*10*fabs(factor) ) { ts->printf( CvTS::LOG, "The normalized histogram has incorrect sum =%g, while it should be =%g\n", sum, factor ); code = CvTS::FAIL_BAD_ACCURACY; } if( code < 0 ) ts->set_failed_test_info( code ); return code; }
bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size region_size) { CV_INSTRUMENT_REGION(); Mat img = _img.getMat(), cornersM = _corners.getMat(); int ncorners = cornersM.checkVector(2, CV_32F); CV_Assert( ncorners >= 0 ); Point2f* corners = cornersM.ptr<Point2f>(); const int nbins = 256; float ranges[] = {0, 256}; const float* _ranges = ranges; Mat hist; Mat black_comp, white_comp; for(int i = 0; i < ncorners; i++) { int channels = 0; Rect roi(cvRound(corners[i].x - region_size.width), cvRound(corners[i].y - region_size.height), region_size.width*2 + 1, region_size.height*2 + 1); Mat img_roi = img(roi); calcHist(&img_roi, 1, &channels, Mat(), hist, 1, &nbins, &_ranges); int black_thresh = 0, white_thresh = 0; segment_hist_max(hist, black_thresh, white_thresh); threshold(img, black_comp, black_thresh, 255.0, THRESH_BINARY_INV); threshold(img, white_comp, white_thresh, 255.0, THRESH_BINARY); const int erode_count = 1; erode(black_comp, black_comp, Mat(), Point(-1, -1), erode_count); erode(white_comp, white_comp, Mat(), Point(-1, -1), erode_count); std::vector<std::vector<Point> > white_contours, black_contours; findContours(black_comp, black_contours, RETR_LIST, CHAIN_APPROX_SIMPLE); findContours(white_comp, white_contours, RETR_LIST, CHAIN_APPROX_SIMPLE); if(black_contours.size() < 5 || white_contours.size() < 5) continue; // find two white and black blobs that are close to the input point std::vector<std::pair<int, float> > white_order, black_order; orderContours(black_contours, corners[i], black_order); orderContours(white_contours, corners[i], white_order); const float max_dist = 10.0f; if(black_order[0].second > max_dist || black_order[1].second > max_dist || white_order[0].second > max_dist || white_order[1].second > max_dist) { continue; // there will be no improvement in this corner position } const std::vector<Point>* quads[4] = {&black_contours[black_order[0].first], &black_contours[black_order[1].first], &white_contours[white_order[0].first], &white_contours[white_order[1].first]}; std::vector<Point2f> quads_approx[4]; Point2f quad_corners[4]; for(int k = 0; k < 4; k++) { std::vector<Point2f> temp; for(size_t j = 0; j < quads[k]->size(); j++) temp.push_back((*quads[k])[j]); approxPolyDP(Mat(temp), quads_approx[k], 0.5, true); findCorner(quads_approx[k], corners[i], quad_corners[k]); quad_corners[k] += Point2f(0.5f, 0.5f); } // cross two lines Point2f origin1 = quad_corners[0]; Point2f dir1 = quad_corners[1] - quad_corners[0]; Point2f origin2 = quad_corners[2]; Point2f dir2 = quad_corners[3] - quad_corners[2]; double angle = acos(dir1.dot(dir2)/(norm(dir1)*norm(dir2))); if(cvIsNaN(angle) || cvIsInf(angle) || angle < 0.5 || angle > CV_PI - 0.5) continue; findLinesCrossPoint(origin1, dir1, origin2, dir2, corners[i]); } return true; }
int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion ) { const float samePointEps = 0.00001; // used to test if two points are the same Point2f vec1[4], vec2[4]; Point2f pts1[4], pts2[4]; std::vector <Point2f> intersection; rect1.points(pts1); rect2.points(pts2); int ret = INTERSECT_FULL; // Specical case of rect1 == rect2 { bool same = true; for( int i = 0; i < 4; i++ ) { if( fabs(pts1[i].x - pts2[i].x) > samePointEps || (fabs(pts1[i].y - pts2[i].y) > samePointEps) ) { same = false; break; } } if(same) { intersection.resize(4); for( int i = 0; i < 4; i++ ) { intersection[i] = pts1[i]; } Mat(intersection).copyTo(intersectingRegion); return INTERSECT_FULL; } } // Line vector // A line from p1 to p2 is: p1 + (p2-p1)*t, t=[0,1] for( int i = 0; i < 4; i++ ) { vec1[i].x = pts1[(i+1)%4].x - pts1[i].x; vec1[i].y = pts1[(i+1)%4].y - pts1[i].y; vec2[i].x = pts2[(i+1)%4].x - pts2[i].x; vec2[i].y = pts2[(i+1)%4].y - pts2[i].y; } // Line test - test all line combos for intersection for( int i = 0; i < 4; i++ ) { for( int j = 0; j < 4; j++ ) { // Solve for 2x2 Ax=b float x21 = pts2[j].x - pts1[i].x; float y21 = pts2[j].y - pts1[i].y; float vx1 = vec1[i].x; float vy1 = vec1[i].y; float vx2 = vec2[j].x; float vy2 = vec2[j].y; float det = vx2*vy1 - vx1*vy2; float t1 = (vx2*y21 - vy2*x21) / det; float t2 = (vx1*y21 - vy1*x21) / det; // This takes care of parallel lines if( cvIsInf(t1) || cvIsInf(t2) || cvIsNaN(t1) || cvIsNaN(t2) ) { continue; } if( t1 >= 0.0f && t1 <= 1.0f && t2 >= 0.0f && t2 <= 1.0f ) { float xi = pts1[i].x + vec1[i].x*t1; float yi = pts1[i].y + vec1[i].y*t1; intersection.push_back(Point2f(xi,yi)); } } } if( !intersection.empty() ) { ret = INTERSECT_PARTIAL; } // Check for vertices from rect1 inside recct2 for( int i = 0; i < 4; i++ ) { // We do a sign test to see which side the point lies. // If the point all lie on the same sign for all 4 sides of the rect, // then there's an intersection int posSign = 0; int negSign = 0; float x = pts1[i].x; float y = pts1[i].y; for( int j = 0; j < 4; j++ ) { // line equation: Ax + By + C = 0 // see which side of the line this point is at float A = -vec2[j].y; float B = vec2[j].x; float C = -(A*pts2[j].x + B*pts2[j].y); float s = A*x+ B*y+ C; if( s >= 0 ) { posSign++; } else { negSign++; } } if( posSign == 4 || negSign == 4 ) { intersection.push_back(pts1[i]); } } // Reverse the check - check for vertices from rect2 inside recct1 for( int i = 0; i < 4; i++ ) { // We do a sign test to see which side the point lies. // If the point all lie on the same sign for all 4 sides of the rect, // then there's an intersection int posSign = 0; int negSign = 0; float x = pts2[i].x; float y = pts2[i].y; for( int j = 0; j < 4; j++ ) { // line equation: Ax + By + C = 0 // see which side of the line this point is at float A = -vec1[j].y; float B = vec1[j].x; float C = -(A*pts1[j].x + B*pts1[j].y); float s = A*x + B*y + C; if( s >= 0 ) { posSign++; } else { negSign++; } } if( posSign == 4 || negSign == 4 ) { intersection.push_back(pts2[i]); } } // Get rid of dupes for( int i = 0; i < (int)intersection.size()-1; i++ ) { for( size_t j = i+1; j < intersection.size(); j++ ) { float dx = intersection[i].x - intersection[j].x; float dy = intersection[i].y - intersection[j].y; double d2 = dx*dx + dy*dy; // can be a really small number, need double here if( d2 < samePointEps*samePointEps ) { // Found a dupe, remove it std::swap(intersection[j], intersection.back()); intersection.pop_back(); i--; // restart check } } } if( intersection.empty() ) { return INTERSECT_NONE ; } // If this check fails then it means we're getting dupes, increase samePointEps CV_Assert( intersection.size() <= 8 ); Mat(intersection).copyTo(intersectingRegion); return ret; }
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; }