| 635 | |
| 636 | |
| 637 | CV_IMPL void |
| 638 | cvFitLine( const CvArr* array, int dist, double param, |
| 639 | double reps, double aeps, float *line ) |
| 640 | { |
| 641 | cv::AutoBuffer<schar> buffer; |
| 642 | |
| 643 | schar* points = 0; |
| 644 | union { CvContour contour; CvSeq seq; } header; |
| 645 | CvSeqBlock block; |
| 646 | CvSeq* ptseq = (CvSeq*)array; |
| 647 | int type; |
| 648 | |
| 649 | if( !line ) |
| 650 | CV_Error( CV_StsNullPtr, "NULL pointer to line parameters" ); |
| 651 | |
| 652 | if( CV_IS_SEQ(ptseq) ) |
| 653 | { |
| 654 | type = CV_SEQ_ELTYPE(ptseq); |
| 655 | if( ptseq->total == 0 ) |
| 656 | CV_Error( CV_StsBadSize, "The sequence has no points" ); |
| 657 | if( (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) || |
| 658 | CV_ELEM_SIZE(type) != ptseq->elem_size ) |
| 659 | CV_Error( CV_StsUnsupportedFormat, |
| 660 | "Input sequence must consist of 2d points or 3d points" ); |
| 661 | } |
| 662 | else |
| 663 | { |
| 664 | CvMat* mat = (CvMat*)array; |
| 665 | type = CV_MAT_TYPE(mat->type); |
| 666 | if( !CV_IS_MAT(mat)) |
| 667 | CV_Error( CV_StsBadArg, "Input array is not a sequence nor matrix" ); |
| 668 | |
| 669 | if( !CV_IS_MAT_CONT(mat->type) || |
| 670 | (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) || |
| 671 | (mat->width != 1 && mat->height != 1)) |
| 672 | CV_Error( CV_StsBadArg, |
| 673 | "Input array must be 1d continuous array of 2d or 3d points" ); |
| 674 | |
| 675 | ptseq = cvMakeSeqHeaderForArray( |
| 676 | CV_SEQ_KIND_GENERIC|type, sizeof(CvContour), CV_ELEM_SIZE(type), mat->data.ptr, |
| 677 | mat->width + mat->height - 1, &header.seq, &block ); |
| 678 | } |
| 679 | |
| 680 | if( reps < 0 || aeps < 0 ) |
| 681 | CV_Error( CV_StsOutOfRange, "Both reps and aeps must be non-negative" ); |
| 682 | |
| 683 | if( CV_MAT_DEPTH(type) == CV_32F && ptseq->first->next == ptseq->first ) |
| 684 | { |
| 685 | /* no need to copy data in this case */ |
| 686 | points = ptseq->first->data; |
| 687 | } |
| 688 | else |
| 689 | { |
| 690 | buffer.allocate(ptseq->total*CV_ELEM_SIZE(type)); |
| 691 | points = buffer; |
| 692 | cvCvtSeqToArray( ptseq, points, CV_WHOLE_SEQ ); |
| 693 | |
| 694 | if( CV_MAT_DEPTH(type) != CV_32F ) |
no test coverage detected