| 772 | |
| 773 | |
| 774 | CV_IMPL CvBox2D |
| 775 | cvFitEllipse2( const CvArr* array ) |
| 776 | { |
| 777 | CvBox2D box; |
| 778 | cv::AutoBuffer<double> Ad, bd; |
| 779 | memset( &box, 0, sizeof(box)); |
| 780 | |
| 781 | CvContour contour_header; |
| 782 | CvSeq* ptseq = 0; |
| 783 | CvSeqBlock block; |
| 784 | int n; |
| 785 | |
| 786 | if( CV_IS_SEQ( array )) |
| 787 | { |
| 788 | ptseq = (CvSeq*)array; |
| 789 | if( !CV_IS_SEQ_POINT_SET( ptseq )) |
| 790 | CV_Error( CV_StsBadArg, "Unsupported sequence type" ); |
| 791 | } |
| 792 | else |
| 793 | { |
| 794 | ptseq = cvPointSeqFromMat(CV_SEQ_KIND_GENERIC, array, &contour_header, &block); |
| 795 | } |
| 796 | |
| 797 | n = ptseq->total; |
| 798 | if( n < 5 ) |
| 799 | CV_Error( CV_StsBadSize, "Number of points should be >= 5" ); |
| 800 | |
| 801 | /* |
| 802 | * New fitellipse algorithm, contributed by Dr. Daniel Weiss |
| 803 | */ |
| 804 | CvPoint2D32f c = {0,0}; |
| 805 | double gfp[5], rp[5], t; |
| 806 | CvMat A, b, x; |
| 807 | const double min_eps = 1e-8; |
| 808 | int i, is_float; |
| 809 | CvSeqReader reader; |
| 810 | |
| 811 | Ad.allocate(n*5); |
| 812 | bd.allocate(n); |
| 813 | |
| 814 | // first fit for parameters A - E |
| 815 | A = cvMat( n, 5, CV_64F, Ad ); |
| 816 | b = cvMat( n, 1, CV_64F, bd ); |
| 817 | x = cvMat( 5, 1, CV_64F, gfp ); |
| 818 | |
| 819 | cvStartReadSeq( ptseq, &reader ); |
| 820 | is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2; |
| 821 | |
| 822 | for( i = 0; i < n; i++ ) |
| 823 | { |
| 824 | CvPoint2D32f p; |
| 825 | if( is_float ) |
| 826 | p = *(CvPoint2D32f*)(reader.ptr); |
| 827 | else |
| 828 | { |
| 829 | p.x = (float)((int*)reader.ptr)[0]; |
| 830 | p.y = (float)((int*)reader.ptr)[1]; |
| 831 | } |
no test coverage detected