Exemple #1
0
CvMat cvmat_remove_column(const CvMat*mat, int column)
{
    assert(column<mat->cols && column>=0);
    assert(mat->cols > 1);

    CvMat new_mat = cvMat(mat->rows, mat->cols-1, mat->type, malloc(mat->rows*mat->cols*8));
    int t;
    int size = CV_ELEM_SIZE(mat->type);
    for(t=0;t<mat->rows;t++) {
        int pos = 0;
        int s;
        for(s=0;s<mat->cols;s++) {
            if(s!=column) {
                memcpy(CV_MAT_ELEM_PTR(new_mat, t, pos), CV_MAT_ELEM_PTR((*mat), t, s), size);
                pos++;
            }
        }
    }
    return new_mat;
}
/*
m_buf只在readHeader中被使用
*/
bool  JpegDecoder::readHeader()
{
    bool result = false;
    close();

    JpegState* state = new JpegState;
    m_state = state;
    state->cinfo.err = jpeg_std_error(&state->jerr.pub);
    state->jerr.pub.error_exit = error_exit;

    if( setjmp( state->jerr.setjmp_buffer ) == 0 )
    {
        jpeg_create_decompress( &state->cinfo );

        if( !(m_buf.data.ptr == 0) )
        {
            jpeg_buffer_src(&state->cinfo, &state->source);
            state->source.pub.next_input_byte = m_buf.data.ptr;
            //state->source.pub.bytes_in_buffer = m_buf.cols*m_buf.rows*m_buf.elemSize();//+++CV_ELEM_SIZE
			state->source.pub.bytes_in_buffer = m_buf.cols*m_buf.rows*CV_ELEM_SIZE(m_buf.type);//+++CV_ELEM_SIZE
			
        }
        else
        {
            m_f = fopen( m_filename.c_str(), "rb" );
            if( m_f )
                jpeg_stdio_src( &state->cinfo, m_f );
        }
        jpeg_read_header( &state->cinfo, TRUE );

        m_width = state->cinfo.image_width;
        m_height = state->cinfo.image_height;
        m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1;
        result = true;
    }

    if( !result )
        close();

    return result;
}
Exemple #3
0
// Selects sub-array (no data is copied)
CV_IMPL  CvMat*
cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
{
    CvMat* res = 0;

    CV_FUNCNAME( "cvGetRect" );

    __BEGIN__;

    CvMat stub, *mat = (CvMat*)arr;

    if( !CV_IS_MAT( mat ))
        CV_CALL( mat = cvGetMat( mat, &stub ));

    if( !submat )
        CV_ERROR( CV_StsNullPtr, "" );

    if( (rect.x|rect.y|rect.width|rect.height) < 0 )
        CV_ERROR( CV_StsBadSize, "" );

    if( rect.x + rect.width > mat->cols ||
        rect.y + rect.height > mat->rows )
        CV_ERROR( CV_StsBadSize, "" );

    {
    submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
                       rect.x*CV_ELEM_SIZE(mat->type);
    submat->step = mat->step & (rect.height > 1 ? -1 : 0);
    submat->type =
        (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
        (submat->step == 0 ? CV_MAT_CONT_FLAG : 0);
    submat->rows = rect.height;
    submat->cols = rect.width;
    submat->refcount = 0;
    res = submat;
    }

    __END__;

    return res;
}
Exemple #4
0
	CameraRGB(std::string& propertyPrefix, const Ice::PropertiesPtr propIn)
      : prefix(propertyPrefix),
	imageFmt(),
	imageDescription(new jderobot::ImageDescription()),
	cameraDescription(new jderobot::CameraDescription()),
	replyTask()
	{
	Ice::PropertiesPtr prop = propIn;


	//fill cameraDescription
	cameraDescription->name = prop->getProperty(prefix+"Name");
	if (cameraDescription->name.size() == 0)
		jderobot::Logger::getInstance()->warning( "Camera name not configured" );

	cameraDescription->shortDescription = prop->getProperty(prefix + "ShortDescription");

	//fill imageDescription
	imageDescription->width = prop->getPropertyAsIntWithDefault(prefix+"width",5);;
	imageDescription->height = prop->getPropertyAsIntWithDefault(prefix+"height",5);;


	int fps = prop->getPropertyAsIntWithDefault(prefix+"fps",5);
	//we use formats according to colorspaces
	std::string fmtStr = prop->getPropertyWithDefault(prefix+"Format","ImageRGB8");//default format YUY2
	imageFmt = colorspaces::Image::Format::searchFormat(fmtStr);
	if (!imageFmt)
		jderobot::Logger::getInstance()->warning( "Format " + fmtStr + " unknown" );
	imageDescription->size = imageDescription->width * imageDescription->height * CV_ELEM_SIZE(imageFmt->cvType);
	imageDescription->format = imageFmt->name;

	// Set the formats allowed
	mFormats.push_back(colorspaces::ImageRGB8::FORMAT_RGB8.get()->name);



	jderobot::Logger::getInstance()->info( "Starting thread for camera: " + cameraDescription->name );
	replyTask = new ReplyTask(this,fps, mFormats[0]);

	this->control=replyTask->start();//my own thread
	}
CvMat* cvGetSubRect_d( const CvArr* arr, CvMat* submat, CvRect rect )
{
    CvMat* res = 0;
    CvMat stub, *mat = (CvMat*)arr;

    if( !CV_IS_MAT( mat ))
        mat = cvGetMat( mat, &stub );

    if( !submat )
        CV_Error( CV_StsNullPtr, "" );

    if( (rect.x|rect.y|rect.width|rect.height) < 0 )
        CV_Error( CV_StsBadSize, "" );

    if( rect.x + rect.width > mat->cols ||
        rect.y + rect.height > mat->rows )
        CV_Error( CV_StsBadSize, "" );

    {
        /*
           int* refcount = mat->refcount;

           if( refcount )
           ++*refcount;

           cvDecRefData( submat );
           */
        submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
            rect.x*CV_ELEM_SIZE(mat->type);
        submat->step = mat->step;
        submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
            (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0);
        submat->rows = rect.height;
        submat->cols = rect.width;
        submat->refcount = 0;
        res = submat;
    }

    return res;
}
Exemple #6
0
CV_IMPL CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* arr,
                                  CvContour* contour_header, CvSeqBlock* block )
{
    CvSeq* contour = 0;

    CV_FUNCNAME( "cvPointSeqFromMat" );

    assert( arr != 0 && contour_header != 0 && block != 0 );

    __BEGIN__;
    
    int eltype;
    CvMat* mat = (CvMat*)arr;
    
    if( !CV_IS_MAT( mat ))
        CV_ERROR( CV_StsBadArg, "Input array is not a valid matrix" ); 

    eltype = CV_MAT_TYPE( mat->type );
    if( eltype != CV_32SC2 && eltype != CV_32FC2 )
        CV_ERROR( CV_StsUnsupportedFormat,
        "The matrix can not be converted to point sequence because of "
        "inappropriate element type" );

    if( (mat->width != 1 && mat->height != 1) || !CV_IS_MAT_CONT(mat->type))
        CV_ERROR( CV_StsBadArg,
        "The matrix converted to point sequence must be "
        "1-dimensional and continuous" );

    CV_CALL( cvMakeSeqHeaderForArray(
            (seq_kind & (CV_SEQ_KIND_MASK|CV_SEQ_FLAG_CLOSED)) | eltype,
            sizeof(CvContour), CV_ELEM_SIZE(eltype), mat->data.ptr,
            mat->width*mat->height, (CvSeq*)contour_header, block ));

    contour = (CvSeq*)contour_header;

    __END__;

    return contour;
}
Exemple #7
0
Mat cvarrToMat(const CvArr* arr, bool copyData,
               bool /*allowND*/, int coiMode, AutoBuffer<double>* abuf )
{
    if( !arr )
        return Mat();
    if( CV_IS_MAT_HDR_Z(arr) )
        return cvMatToMat((const CvMat*)arr, copyData);
    if( CV_IS_MATND(arr) )
        return cvMatNDToMat((const CvMatND*)arr, copyData );
    if( CV_IS_IMAGE(arr) )
    {
        const IplImage* iplimg = (const IplImage*)arr;
        if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 )
            CV_Error(CV_BadCOI, "COI is not supported by the function");
        return iplImageToMat(iplimg, copyData);
    }
    if( CV_IS_SEQ(arr) )
    {
        CvSeq* seq = (CvSeq*)arr;
        int total = seq->total, type = CV_MAT_TYPE(seq->flags), esz = seq->elem_size;
        if( total == 0 )
            return Mat();
        CV_Assert(total > 0 && CV_ELEM_SIZE(seq->flags) == esz);
        if(!copyData && seq->first->next == seq->first)
            return Mat(total, 1, type, seq->first->data);
        if( abuf )
        {
            abuf->allocate(((size_t)total*esz + sizeof(double)-1)/sizeof(double));
            double* bufdata = abuf->data();
            cvCvtSeqToArray(seq, bufdata, CV_WHOLE_SEQ);
            return Mat(total, 1, type, bufdata);
        }

        Mat buf(total, 1, type);
        cvCvtSeqToArray(seq, buf.ptr(), CV_WHOLE_SEQ);
        return buf;
    }
    CV_Error(CV_StsBadArg, "Unknown array type");
}
void cvArrPrint(CvArr * arr){
  CvMat * mat;
  CvMat stub;

  mat = cvGetMat(arr, &stub);
  
  int cn = CV_MAT_CN(mat->type);
  int depth = CV_MAT_DEPTH(mat->type);
  int step = MAX(mat->step, cn*mat->cols*CV_ELEM_SIZE(depth));


  switch(depth){
    case CV_8U:
      cv_arr_write(stdout, "%u", (uchar *)mat->data.ptr, mat->rows, cn, step);
      break;
    case CV_8S:
      cv_arr_write(stdout, "%d", (char *)mat->data.ptr, mat->rows, cn, step);
      break;
    case CV_16U:
      cv_arr_write(stdout, "%u", (ushort *)mat->data.ptr, mat->rows, cn, step);
      break;
    case CV_16S:
      cv_arr_write(stdout, "%d", (short *)mat->data.ptr, mat->rows, cn, step);
      break;
    case CV_32S:
      cv_arr_write(stdout, "%d", (int *)mat->data.ptr, mat->rows, cn, step);
      break;
    case CV_32F:
      cv_arr_write(stdout, "%f", (float *)mat->data.ptr, mat->rows, cn, step);
      break;
    case CV_64F:
      cv_arr_write(stdout, "%g", (double *)mat->data.ptr, mat->rows, cn, step);
      break;
    default:
      CV_Error( CV_StsError, "Unknown element type");
      break;
  }
}
Exemple #9
0
CV_IMPL int
cvSampleLine( const void* img, CvPoint pt1, CvPoint pt2,
              void* _buffer, int connectivity )
{
    int count = -1;
    
    CV_FUNCNAME( "cvSampleLine" );

    __BEGIN__;
    
    int i, coi = 0, pix_size;
    CvMat stub, *mat = (CvMat*)img;
    CvLineIterator iterator;
    uchar* buffer = (uchar*)_buffer;

    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));

    if( coi != 0 )
        CV_ERROR( CV_BadCOI, "" );

    if( !buffer )
        CV_ERROR( CV_StsNullPtr, "" );

    CV_CALL( count = cvInitLineIterator( mat, pt1, pt2, &iterator, connectivity ));

    pix_size = CV_ELEM_SIZE(mat->type);
    for( i = 0; i < count; i++ )
    {
        for( int j = 0; j < pix_size; j++ )
            buffer[j] = iterator.ptr[j];
        buffer += pix_size;
        CV_NEXT_LINE_POINT( iterator );
    }

    __END__;

    return count;
}
Exemple #10
0
CV_IMPL void
cvDeInterlace( const CvArr* framearr, CvArr* fieldEven, CvArr* fieldOdd )
{
    CV_FUNCNAME("cvDeInterlace");
    
    __BEGIN__;

    CvMat frame_stub, *frame = (CvMat*)framearr;
    CvMat even_stub, *even = (CvMat*)fieldEven;
    CvMat odd_stub, *odd = (CvMat*)fieldOdd;
    CvSize size;
    int y;

    CV_CALL( frame = cvGetMat( frame, &frame_stub ));
    CV_CALL( even = cvGetMat( even, &even_stub ));
    CV_CALL( odd = cvGetMat( odd, &odd_stub ));

    if( !CV_ARE_TYPES_EQ( frame, even ) || !CV_ARE_TYPES_EQ( frame, odd ))
        CV_ERROR( CV_StsUnmatchedFormats, "All the input images must have the same type" );

    if( frame->cols != even->cols || frame->cols != odd->cols ||
        frame->rows != even->rows*2 || odd->rows != even->rows )
        CV_ERROR( CV_StsUnmatchedSizes, "Uncorrelated sizes of the input image and output fields" );

    size = cvGetMatSize( even );
    size.width *= CV_ELEM_SIZE( even->type );

    for( y = 0; y < size.height; y++ )
    {
        memcpy( even->data.ptr + even->step*y,
                frame->data.ptr + frame->step*y*2, size.width );
        memcpy( odd->data.ptr + even->step*y,
                frame->data.ptr + frame->step*(y*2+1), size.width );
    }  

    __END__;
}
Exemple #11
0
// This function create cross-validation EstimateModel.
ML_IMPL CvStatModel*
cvCreateCrossValidationEstimateModel(
    int                samples_all,
    const CvStatModelParams* estimateParams,
    const CvMat*             sampleIdx)
{
    CvStatModel*            model   = NULL;
    CvCrossValidationModel* crVal   = NULL;

    CV_FUNCNAME ("cvCreateCrossValidationEstimateModel");
    __BEGIN__

    int  k_fold = 10;

    int  i, j, k, s_len;
    int  samples_selected;
    CvRNG rng;
    CvRNG* prng;
    int* res_s_data;
    int* te_s_data;
    int* folds;

    rng = cvRNG(cvGetTickCount());
    cvRandInt (&rng);
    cvRandInt (&rng);
    cvRandInt (&rng);
    cvRandInt (&rng);
// Check input parameters.
    if (estimateParams)
        k_fold = ((CvCrossValidationParams*)estimateParams)->k_fold;
    if (!k_fold)
    {
        CV_ERROR (CV_StsBadArg, "Error in parameters of cross-validation (k_fold == 0)!");
    }
    if (samples_all <= 0)
    {
        CV_ERROR (CV_StsBadArg, "<samples_all> should be positive!");
    }

// Alloc memory and fill standart StatModel's fields.
    CV_CALL (crVal = (CvCrossValidationModel*)cvCreateStatModel (
                         CV_STAT_MODEL_MAGIC_VAL | CV_CROSSVAL_MAGIC_VAL,
                         sizeof(CvCrossValidationModel),
                         cvReleaseCrossValidationModel,
                         NULL, NULL));
    crVal->current_fold    = -1;
    crVal->folds_all       = k_fold;
    if (estimateParams && ((CvCrossValidationParams*)estimateParams)->is_regression)
        crVal->is_regression = 1;
    else
        crVal->is_regression = 0;
    if (estimateParams && ((CvCrossValidationParams*)estimateParams)->rng)
        prng = ((CvCrossValidationParams*)estimateParams)->rng;
    else
        prng = &rng;

    // Check and preprocess sample indices.
    if (sampleIdx)
    {
        int s_step;
        int s_type = 0;

        if (!CV_IS_MAT (sampleIdx))
            CV_ERROR (CV_StsBadArg, "Invalid sampleIdx array");

        if (sampleIdx->rows != 1 && sampleIdx->cols != 1)
            CV_ERROR (CV_StsBadSize, "sampleIdx array must be 1-dimensional");

        s_len = sampleIdx->rows + sampleIdx->cols - 1;
        s_step = sampleIdx->rows == 1 ?
                 1 : sampleIdx->step / CV_ELEM_SIZE(sampleIdx->type);

        s_type = CV_MAT_TYPE (sampleIdx->type);

        switch (s_type)
        {
        case CV_8UC1:
        case CV_8SC1:
        {
            uchar* s_data = sampleIdx->data.ptr;

            // sampleIdx is array of 1's and 0's -
            // i.e. it is a mask of the selected samples
            if( s_len != samples_all )
                CV_ERROR (CV_StsUnmatchedSizes,
                          "Sample mask should contain as many elements as the total number of samples");

            samples_selected = 0;
            for (i = 0; i < s_len; i++)
                samples_selected += s_data[i * s_step] != 0;

            if (samples_selected == 0)
                CV_ERROR (CV_StsOutOfRange, "No samples is selected!");
        }
        s_len = samples_selected;
        break;
        case CV_32SC1:
            if (s_len > samples_all)
                CV_ERROR (CV_StsOutOfRange,
                          "sampleIdx array may not contain more elements than the total number of samples");
            samples_selected = s_len;
            break;
        default:
            CV_ERROR (CV_StsUnsupportedFormat, "Unsupported sampleIdx array data type "
                      "(it should be 8uC1, 8sC1 or 32sC1)");
        }

        // Alloc additional memory for internal Idx and fill it.
        /*!!*/  CV_CALL (res_s_data = crVal->sampleIdxAll =
                                          (int*)cvAlloc (2 * s_len * sizeof(int)));

        if (s_type < CV_32SC1)
        {
            uchar* s_data = sampleIdx->data.ptr;
            for (i = 0; i < s_len; i++)
                if (s_data[i * s_step])
                {
                    *res_s_data++ = i;
                }
            res_s_data = crVal->sampleIdxAll;
        }
        else
        {
            int* s_data = sampleIdx->data.i;
            int out_of_order = 0;

            for (i = 0; i < s_len; i++)
            {
                res_s_data[i] = s_data[i * s_step];
                if (i > 0 && res_s_data[i] < res_s_data[i - 1])
                    out_of_order = 1;
            }

            if (out_of_order)
                qsort (res_s_data, s_len, sizeof(res_s_data[0]), icvCmpIntegers);

            if (res_s_data[0] < 0 ||
                    res_s_data[s_len - 1] >= samples_all)
                CV_ERROR (CV_StsBadArg, "There are out-of-range sample indices");
            for (i = 1; i < s_len; i++)
                if (res_s_data[i] <= res_s_data[i - 1])
                    CV_ERROR (CV_StsBadArg, "There are duplicated");
        }
    }
    else // if (sampleIdx)
    {
        // Alloc additional memory for internal Idx and fill it.
        s_len = samples_all;
        CV_CALL (res_s_data = crVal->sampleIdxAll = (int*)cvAlloc (2 * s_len * sizeof(int)));
        for (i = 0; i < s_len; i++)
        {
            *res_s_data++ = i;
        }
        res_s_data = crVal->sampleIdxAll;
    } // if (sampleIdx) ... else

// Resort internal Idx.
    te_s_data = res_s_data + s_len;
    for (i = s_len; i > 1; i--)
    {
        j = cvRandInt (prng) % i;
        k = *(--te_s_data);
        *te_s_data = res_s_data[j];
        res_s_data[j] = k;
    }

// Duplicate resorted internal Idx.
// It will be used to simplify operation of getting trainIdx.
    te_s_data = res_s_data + s_len;
    for (i = 0; i < s_len; i++)
    {
        *te_s_data++ = *res_s_data++;
    }

// Cut sampleIdxAll to parts.
    if (k_fold > 0)
    {
        if (k_fold > s_len)
        {
            CV_ERROR (CV_StsBadArg,
                      "Error in parameters of cross-validation ('k_fold' > #samples)!");
        }
        folds = crVal->folds = (int*) cvAlloc ((k_fold + 1) * sizeof (int));
        *folds++ = 0;
        for (i = 1; i < k_fold; i++)
        {
            *folds++ = cvRound (i * s_len * 1. / k_fold);
        }
        *folds = s_len;
        folds = crVal->folds;

        crVal->max_fold_size = (s_len - 1) / k_fold + 1;
    }
    else
    {
        k = -k_fold;
        crVal->max_fold_size = k;
        if (k >= s_len)
        {
            CV_ERROR (CV_StsBadArg,
                      "Error in parameters of cross-validation (-'k_fold' > #samples)!");
        }
        crVal->folds_all = k = (s_len - 1) / k + 1;

        folds = crVal->folds = (int*) cvAlloc ((k + 1) * sizeof (int));
        for (i = 0; i < k; i++)
        {
            *folds++ = -i * k_fold;
        }
        *folds = s_len;
        folds = crVal->folds;
    }

// Prepare other internal fields to working.
    CV_CALL (crVal->predict_results = cvCreateMat (1, samples_all, CV_32FC1));
    CV_CALL (crVal->sampleIdxEval = cvCreateMatHeader (1, 1, CV_32SC1));
    CV_CALL (crVal->sampleIdxTrain = cvCreateMatHeader (1, 1, CV_32SC1));
    crVal->sampleIdxEval->cols = 0;
    crVal->sampleIdxTrain->cols = 0;
    crVal->samples_all = s_len;
    crVal->is_checked = 1;

    crVal->getTrainIdxMat = cvCrossValGetTrainIdxMatrix;
    crVal->getCheckIdxMat = cvCrossValGetCheckIdxMatrix;
    crVal->nextStep = cvCrossValNextStep;
    crVal->check = cvCrossValCheckClassifier;
    crVal->getResult = cvCrossValGetResult;
    crVal->reset = cvCrossValReset;

    model = (CvStatModel*)crVal;

    __END__

    if (!model)
    {
        cvReleaseCrossValidationModel ((CvStatModel**)&crVal);
    }

    return model;
} // End of cvCreateCrossValidationEstimateModel
Exemple #12
0
CV_IMPL void
cvFloodFill( CvArr* arr, CvPoint seed_point,
             CvScalar newVal, CvScalar lo_diff, CvScalar up_diff,
             CvConnectedComp* comp, int flags, CvArr* maskarr )
{
    cv::Ptr<CvMat> tempMask;
    std::vector<CvFFillSegment> buffer;

    if( comp )
        memset( comp, 0, sizeof(*comp) );

    int i, type, depth, cn, is_simple;
    int buffer_size, connectivity = flags & 255;
    union {
        uchar b[4];
        int i[4];
        float f[4];
        double _[4];
    } nv_buf;
    nv_buf._[0] = nv_buf._[1] = nv_buf._[2] = nv_buf._[3] = 0;

    struct { cv::Vec3b b; cv::Vec3i i; cv::Vec3f f; } ld_buf, ud_buf;
    CvMat stub, *img = cvGetMat(arr, &stub);
    CvMat maskstub, *mask = (CvMat*)maskarr;
    CvSize size;

    type = CV_MAT_TYPE( img->type );
    depth = CV_MAT_DEPTH(type);
    cn = CV_MAT_CN(type);

    if( connectivity == 0 )
        connectivity = 4;
    else if( connectivity != 4 && connectivity != 8 )
        CV_Error( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" );

    is_simple = mask == 0 && (flags & CV_FLOODFILL_MASK_ONLY) == 0;

    for( i = 0; i < cn; i++ )
    {
        if( lo_diff.val[i] < 0 || up_diff.val[i] < 0 )
            CV_Error( CV_StsBadArg, "lo_diff and up_diff must be non-negative" );
        is_simple &= fabs(lo_diff.val[i]) < DBL_EPSILON && fabs(up_diff.val[i]) < DBL_EPSILON;
    }

    size = cvGetMatSize( img );

    if( (unsigned)seed_point.x >= (unsigned)size.width ||
        (unsigned)seed_point.y >= (unsigned)size.height )
        CV_Error( CV_StsOutOfRange, "Seed point is outside of image" );

    cvScalarToRawData( &newVal, &nv_buf, type, 0 );
    buffer_size = MAX( size.width, size.height ) * 2;
    buffer.resize( buffer_size );

    if( is_simple )
    {
        int elem_size = CV_ELEM_SIZE(type);
        const uchar* seed_ptr = img->data.ptr + img->step*seed_point.y + elem_size*seed_point.x;

        for(i = 0; i < elem_size; i++)
            if (seed_ptr[i] != nv_buf.b[i])
                break;

        if (i != elem_size)
        {
            if( type == CV_8UC1 )
                icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.b[0],
                                  comp, flags, &buffer);
            else if( type == CV_8UC3 )
                icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3b(nv_buf.b),
                                  comp, flags, &buffer);
            else if( type == CV_32SC1 )
                icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.i[0],
                                  comp, flags, &buffer);
            else if( type == CV_32FC1 )
                icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, nv_buf.f[0],
                                  comp, flags, &buffer);
            else if( type == CV_32SC3 )
                icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3i(nv_buf.i),
                                  comp, flags, &buffer);
            else if( type == CV_32FC3 )
                icvFloodFill_CnIR(img->data.ptr, img->step, size, seed_point, cv::Vec3f(nv_buf.f),
                                  comp, flags, &buffer);
            else
                CV_Error( CV_StsUnsupportedFormat, "" );
            return;
        }
    }

    if( !mask )
    {
        /* created mask will be 8-byte aligned */
        tempMask = cvCreateMat( size.height + 2, (size.width + 9) & -8, CV_8UC1 );
        mask = tempMask;
    }
    else
    {
        mask = cvGetMat( mask, &maskstub );
        if( !CV_IS_MASK_ARR( mask ))
            CV_Error( CV_StsBadMask, "" );

        if( mask->width != size.width + 2 || mask->height != size.height + 2 )
            CV_Error( CV_StsUnmatchedSizes, "mask must be 2 pixel wider "
                                   "and 2 pixel taller than filled image" );
    }

    int width = tempMask ? mask->step : size.width + 2;
    uchar* mask_row = mask->data.ptr + mask->step;
    memset( mask_row - mask->step, 1, width );

    for( i = 1; i <= size.height; i++, mask_row += mask->step )
    {
        if( tempMask )
            memset( mask_row, 0, width );
        mask_row[0] = mask_row[size.width+1] = (uchar)1;
    }
    memset( mask_row, 1, width );

    if( depth == CV_8U )
        for( i = 0; i < cn; i++ )
        {
            int t = cvFloor(lo_diff.val[i]);
            ld_buf.b[i] = CV_CAST_8U(t);
            t = cvFloor(up_diff.val[i]);
            ud_buf.b[i] = CV_CAST_8U(t);
        }
    else if( depth == CV_32S )
        for( i = 0; i < cn; i++ )
        {
            int t = cvFloor(lo_diff.val[i]);
            ld_buf.i[i] = t;
            t = cvFloor(up_diff.val[i]);
            ud_buf.i[i] = t;
        }
    else if( depth == CV_32F )
        for( i = 0; i < cn; i++ )
        {
            ld_buf.f[i] = (float)lo_diff.val[i];
            ud_buf.f[i] = (float)up_diff.val[i];
        }
    else
        CV_Error( CV_StsUnsupportedFormat, "" );

    if( type == CV_8UC1 )
        icvFloodFillGrad_CnIR<uchar, int, Diff8uC1>(
                              img->data.ptr, img->step, mask->data.ptr, mask->step,
                              size, seed_point, nv_buf.b[0],
                              Diff8uC1(ld_buf.b[0], ud_buf.b[0]),
                              comp, flags, &buffer);
    else if( type == CV_8UC3 )
        icvFloodFillGrad_CnIR<cv::Vec3b, cv::Vec3i, Diff8uC3>(
                              img->data.ptr, img->step, mask->data.ptr, mask->step,
                              size, seed_point, cv::Vec3b(nv_buf.b),
                              Diff8uC3(ld_buf.b, ud_buf.b),
                              comp, flags, &buffer);
    else if( type == CV_32SC1 )
        icvFloodFillGrad_CnIR<int, int, Diff32sC1>(
                              img->data.ptr, img->step, mask->data.ptr, mask->step,
                              size, seed_point, nv_buf.i[0],
                              Diff32sC1(ld_buf.i[0], ud_buf.i[0]),
                              comp, flags, &buffer);
    else if( type == CV_32SC3 )
        icvFloodFillGrad_CnIR<cv::Vec3i, cv::Vec3i, Diff32sC3>(
                              img->data.ptr, img->step, mask->data.ptr, mask->step,
                              size, seed_point, cv::Vec3i(nv_buf.i),
                              Diff32sC3(ld_buf.i, ud_buf.i),
                              comp, flags, &buffer);
    else if( type == CV_32FC1 )
        icvFloodFillGrad_CnIR<float, float, Diff32fC1>(
                              img->data.ptr, img->step, mask->data.ptr, mask->step,
                              size, seed_point, nv_buf.f[0],
                              Diff32fC1(ld_buf.f[0], ud_buf.f[0]),
                              comp, flags, &buffer);
    else if( type == CV_32FC3 )
        icvFloodFillGrad_CnIR<cv::Vec3f, cv::Vec3f, Diff32fC3>(
                              img->data.ptr, img->step, mask->data.ptr, mask->step,
                              size, seed_point, cv::Vec3f(nv_buf.f),
                              Diff32fC3(ld_buf.f, ud_buf.f),
                              comp, flags, &buffer);
    else
        CV_Error(CV_StsUnsupportedFormat, "");
}
Exemple #13
0
CV_IMPL void
cvPreCornerDetect( const void* srcarr, void* dstarr, int aperture_size )
{
    CvSepFilter dx_filter, dy_filter, d2x_filter, d2y_filter, dxy_filter;
    CvMat *Dx = 0, *Dy = 0, *D2x = 0, *D2y = 0, *Dxy = 0;
    CvMat *tempsrc = 0;

    int buf_size = 1 << 12;

    CV_FUNCNAME( "cvPreCornerDetect" );

    __BEGIN__;

    int i, j, y, dst_y = 0, max_dy, delta = 0;
    int temp_step = 0, d_step;
    uchar* shifted_ptr = 0;
    int depth, d_depth;
    int stage = CV_START;
    CvSobelFixedIPPFunc ipp_sobel_vert = 0, ipp_sobel_horiz = 0,
                        ipp_sobel_vert_second = 0, ipp_sobel_horiz_second = 0,
                        ipp_sobel_cross = 0;
    CvSize el_size, size, stripe_size;
    int aligned_width;
    CvPoint el_anchor;
    double factor;
    CvMat stub, *src = (CvMat*)srcarr;
    CvMat dststub, *dst = (CvMat*)dstarr;
    bool use_ipp = false;

    CV_CALL( src = cvGetMat( srcarr, &stub ));
    CV_CALL( dst = cvGetMat( dst, &dststub ));

    if( CV_MAT_TYPE(src->type) != CV_8UC1 && CV_MAT_TYPE(src->type) != CV_32FC1 ||
            CV_MAT_TYPE(dst->type) != CV_32FC1 )
        CV_ERROR( CV_StsUnsupportedFormat, "Input must be 8uC1 or 32fC1, output must be 32fC1" );

    if( !CV_ARE_SIZES_EQ( src, dst ))
        CV_ERROR( CV_StsUnmatchedSizes, "" );

    if( aperture_size == CV_SCHARR )
        CV_ERROR( CV_StsOutOfRange, "CV_SCHARR is not supported by this function" );

    if( aperture_size < 3 || aperture_size > 7 || !(aperture_size & 1) )
        CV_ERROR( CV_StsOutOfRange,
                  "Derivative filter aperture size must be 3, 5 or 7" );

    depth = CV_MAT_DEPTH(src->type);
    d_depth = depth == CV_8U ? CV_16S : CV_32F;

    size = cvGetMatSize(src);
    aligned_width = cvAlign(size.width, 4);

    el_size = cvSize( aperture_size, aperture_size );
    el_anchor = cvPoint( aperture_size/2, aperture_size/2 );

    if( aperture_size <= 5 && icvFilterSobelVert_8u16s_C1R_p )
    {
        if( depth == CV_8U )
        {
            ipp_sobel_vert = icvFilterSobelVert_8u16s_C1R_p;
            ipp_sobel_horiz = icvFilterSobelHoriz_8u16s_C1R_p;
            ipp_sobel_vert_second = icvFilterSobelVertSecond_8u16s_C1R_p;
            ipp_sobel_horiz_second = icvFilterSobelHorizSecond_8u16s_C1R_p;
            ipp_sobel_cross = icvFilterSobelCross_8u16s_C1R_p;
        }
        else if( depth == CV_32F )
        {
            ipp_sobel_vert = icvFilterSobelVert_32f_C1R_p;
            ipp_sobel_horiz = icvFilterSobelHoriz_32f_C1R_p;
            ipp_sobel_vert_second = icvFilterSobelVertSecond_32f_C1R_p;
            ipp_sobel_horiz_second = icvFilterSobelHorizSecond_32f_C1R_p;
            ipp_sobel_cross = icvFilterSobelCross_32f_C1R_p;
        }
    }

    if( ipp_sobel_vert && ipp_sobel_horiz && ipp_sobel_vert_second &&
            ipp_sobel_horiz_second && ipp_sobel_cross )
    {
        CV_CALL( tempsrc = icvIPPFilterInit( src, buf_size, el_size ));
        shifted_ptr = tempsrc->data.ptr + el_anchor.y*tempsrc->step +
                      el_anchor.x*CV_ELEM_SIZE(depth);
        temp_step = tempsrc->step ? tempsrc->step : CV_STUB_STEP;
        max_dy = tempsrc->rows - aperture_size + 1;
        use_ipp = true;
    }
    else
    {
        ipp_sobel_vert = ipp_sobel_horiz = 0;
        ipp_sobel_vert_second = ipp_sobel_horiz_second = ipp_sobel_cross = 0;
        dx_filter.init_deriv( size.width, depth, d_depth, 1, 0, aperture_size );
        dy_filter.init_deriv( size.width, depth, d_depth, 0, 1, aperture_size );
        d2x_filter.init_deriv( size.width, depth, d_depth, 2, 0, aperture_size );
        d2y_filter.init_deriv( size.width, depth, d_depth, 0, 2, aperture_size );
        dxy_filter.init_deriv( size.width, depth, d_depth, 1, 1, aperture_size );
        max_dy = buf_size / src->cols;
        max_dy = MAX( max_dy, aperture_size );
    }

    CV_CALL( Dx = cvCreateMat( max_dy, aligned_width, d_depth ));
    CV_CALL( Dy = cvCreateMat( max_dy, aligned_width, d_depth ));
    CV_CALL( D2x = cvCreateMat( max_dy, aligned_width, d_depth ));
    CV_CALL( D2y = cvCreateMat( max_dy, aligned_width, d_depth ));
    CV_CALL( Dxy = cvCreateMat( max_dy, aligned_width, d_depth ));
    Dx->cols = Dy->cols = D2x->cols = D2y->cols = Dxy->cols = size.width;

    if( !use_ipp )
        max_dy -= aperture_size - 1;
    d_step = Dx->step ? Dx->step : CV_STUB_STEP;

    stripe_size = size;

    factor = 1 << (aperture_size - 1);
    if( depth == CV_8U )
        factor *= 255;
    factor = 1./(factor * factor * factor);

    aperture_size = aperture_size * 10 + aperture_size;

    for( y = 0; y < size.height; y += delta )
    {
        if( !use_ipp )
        {
            delta = MIN( size.height - y, max_dy );
            CvRect roi = cvRect(0,y,size.width,delta);
            CvPoint origin=cvPoint(0,0);

            if( y + delta == size.height )
                stage = stage & CV_START ? CV_START + CV_END : CV_END;

            dx_filter.process(src,Dx,roi,origin,stage);
            dy_filter.process(src,Dy,roi,origin,stage);
            d2x_filter.process(src,D2x,roi,origin,stage);
            d2y_filter.process(src,D2y,roi,origin,stage);
            stripe_size.height = dxy_filter.process(src,Dxy,roi,origin,stage);
        }
        else
        {
            delta = icvIPPFilterNextStripe( src, tempsrc, y, el_size, el_anchor );
            stripe_size.height = delta;

            IPPI_CALL( ipp_sobel_vert( shifted_ptr, temp_step,
                                       Dx->data.ptr, d_step, stripe_size, aperture_size ));
            IPPI_CALL( ipp_sobel_horiz( shifted_ptr, temp_step,
                                        Dy->data.ptr, d_step, stripe_size, aperture_size ));
            IPPI_CALL( ipp_sobel_vert_second( shifted_ptr, temp_step,
                                              D2x->data.ptr, d_step, stripe_size, aperture_size ));
            IPPI_CALL( ipp_sobel_horiz_second( shifted_ptr, temp_step,
                                               D2y->data.ptr, d_step, stripe_size, aperture_size ));
            IPPI_CALL( ipp_sobel_cross( shifted_ptr, temp_step,
                                        Dxy->data.ptr, d_step, stripe_size, aperture_size ));
        }

        for( i = 0; i < stripe_size.height; i++, dst_y++ )
        {
            float* dstdata = (float*)(dst->data.ptr + dst_y*dst->step);

            if( d_depth == CV_16S )
            {
                const short* dxdata = (const short*)(Dx->data.ptr + i*Dx->step);
                const short* dydata = (const short*)(Dy->data.ptr + i*Dy->step);
                const short* d2xdata = (const short*)(D2x->data.ptr + i*D2x->step);
                const short* d2ydata = (const short*)(D2y->data.ptr + i*D2y->step);
                const short* dxydata = (const short*)(Dxy->data.ptr + i*Dxy->step);

                for( j = 0; j < stripe_size.width; j++ )
                {
                    double dx = dxdata[j];
                    double dx2 = dx * dx;
                    double dy = dydata[j];
                    double dy2 = dy * dy;

                    dstdata[j] = (float)(factor*(dx2*d2ydata[j] + dy2*d2xdata[j] - 2*dx*dy*dxydata[j]));
                }
            }
            else
            {
                const float* dxdata = (const float*)(Dx->data.ptr + i*Dx->step);
                const float* dydata = (const float*)(Dy->data.ptr + i*Dy->step);
                const float* d2xdata = (const float*)(D2x->data.ptr + i*D2x->step);
                const float* d2ydata = (const float*)(D2y->data.ptr + i*D2y->step);
                const float* dxydata = (const float*)(Dxy->data.ptr + i*Dxy->step);

                for( j = 0; j < stripe_size.width; j++ )
                {
                    double dx = dxdata[j];
                    double dy = dydata[j];
                    dstdata[j] = (float)(factor*(dx*dx*d2ydata[j] + dy*dy*d2xdata[j] - 2*dx*dy*dxydata[j]));
                }
            }
        }

        stage = CV_MIDDLE;
    }

    __END__;

    cvReleaseMat( &Dx );
    cvReleaseMat( &Dy );
    cvReleaseMat( &D2x );
    cvReleaseMat( &D2y );
    cvReleaseMat( &Dxy );
    cvReleaseMat( &tempsrc );
}
Exemple #14
0
static void
icvCornerEigenValsVecs( const CvMat* src, CvMat* eigenv, int block_size,
                        int aperture_size, int op_type, double k=0. )
{
    CvSepFilter dx_filter, dy_filter;
    CvBoxFilter blur_filter;
    CvMat *tempsrc = 0;
    CvMat *Dx = 0, *Dy = 0, *cov = 0;
    CvMat *sqrt_buf = 0;

    int buf_size = 1 << 12;

    CV_FUNCNAME( "icvCornerEigenValsVecs" );

    __BEGIN__;

    int i, j, y, dst_y = 0, max_dy, delta = 0;
    int aperture_size0 = aperture_size;
    int temp_step = 0, d_step;
    uchar* shifted_ptr = 0;
    int depth, d_depth;
    int stage = CV_START;
    CvSobelFixedIPPFunc ipp_sobel_vert = 0, ipp_sobel_horiz = 0;
    CvFilterFixedIPPFunc ipp_scharr_vert = 0, ipp_scharr_horiz = 0;
    CvSize el_size, size, stripe_size;
    int aligned_width;
    CvPoint el_anchor;
    double factorx, factory;
    bool use_ipp = false;

    if( block_size < 3 || !(block_size & 1) )
        CV_ERROR( CV_StsOutOfRange, "averaging window size must be an odd number >= 3" );

    if( aperture_size < 3 && aperture_size != CV_SCHARR || !(aperture_size & 1) )
        CV_ERROR( CV_StsOutOfRange,
                  "Derivative filter aperture size must be a positive odd number >=3 or CV_SCHARR" );

    depth = CV_MAT_DEPTH(src->type);
    d_depth = depth == CV_8U ? CV_16S : CV_32F;

    size = cvGetMatSize(src);
    aligned_width = cvAlign(size.width, 4);

    aperture_size = aperture_size == CV_SCHARR ? 3 : aperture_size;
    el_size = cvSize( aperture_size, aperture_size );
    el_anchor = cvPoint( aperture_size/2, aperture_size/2 );

    if( aperture_size <= 5 && icvFilterSobelVert_8u16s_C1R_p )
    {
        if( depth == CV_8U && aperture_size0 == CV_SCHARR )
        {
            ipp_scharr_vert = icvFilterScharrVert_8u16s_C1R_p;
            ipp_scharr_horiz = icvFilterScharrHoriz_8u16s_C1R_p;
        }
        else if( depth == CV_32F && aperture_size0 == CV_SCHARR )
        {
            ipp_scharr_vert = icvFilterScharrVert_32f_C1R_p;
            ipp_scharr_horiz = icvFilterScharrHoriz_32f_C1R_p;
        }
        else if( depth == CV_8U )
        {
            ipp_sobel_vert = icvFilterSobelVert_8u16s_C1R_p;
            ipp_sobel_horiz = icvFilterSobelHoriz_8u16s_C1R_p;
        }
        else if( depth == CV_32F )
        {
            ipp_sobel_vert = icvFilterSobelVert_32f_C1R_p;
            ipp_sobel_horiz = icvFilterSobelHoriz_32f_C1R_p;
        }
    }

    if( ipp_sobel_vert && ipp_sobel_horiz ||
            ipp_scharr_vert && ipp_scharr_horiz )
    {
        CV_CALL( tempsrc = icvIPPFilterInit( src, buf_size,
                                             cvSize(el_size.width,el_size.height + block_size)));
        shifted_ptr = tempsrc->data.ptr + el_anchor.y*tempsrc->step +
                      el_anchor.x*CV_ELEM_SIZE(depth);
        temp_step = tempsrc->step ? tempsrc->step : CV_STUB_STEP;
        max_dy = tempsrc->rows - aperture_size + 1;
        use_ipp = true;
    }
    else
    {
        ipp_sobel_vert = ipp_sobel_horiz = 0;
        ipp_scharr_vert = ipp_scharr_horiz = 0;

        CV_CALL( dx_filter.init_deriv( size.width, depth, d_depth, 1, 0, aperture_size0 ));
        CV_CALL( dy_filter.init_deriv( size.width, depth, d_depth, 0, 1, aperture_size0 ));
        max_dy = buf_size / src->cols;
        max_dy = MAX( max_dy, aperture_size + block_size );
    }

    CV_CALL( Dx = cvCreateMat( max_dy, aligned_width, d_depth ));
    CV_CALL( Dy = cvCreateMat( max_dy, aligned_width, d_depth ));
    CV_CALL( cov = cvCreateMat( max_dy + block_size + 1, size.width, CV_32FC3 ));
    CV_CALL( sqrt_buf = cvCreateMat( 2, size.width, CV_32F ));
    Dx->cols = Dy->cols = size.width;

    if( !use_ipp )
        max_dy -= aperture_size - 1;
    d_step = Dx->step ? Dx->step : CV_STUB_STEP;

    CV_CALL(blur_filter.init(size.width, CV_32FC3, CV_32FC3, 0, cvSize(block_size,block_size)));
    stripe_size = size;

    factorx = (double)(1 << (aperture_size - 1)) * block_size;
    if( aperture_size0 == CV_SCHARR )
        factorx *= 2;
    if( depth == CV_8U )
        factorx *= 255.;
    factory = factorx = 1./factorx;
    if( ipp_sobel_vert )
        factory = -factory;

    for( y = 0; y < size.height; y += delta )
    {
        if( !use_ipp )
        {
            delta = MIN( size.height - y, max_dy );
            if( y + delta == size.height )
                stage = stage & CV_START ? CV_START + CV_END : CV_END;
            dx_filter.process( src, Dx, cvRect(0,y,-1,delta), cvPoint(0,0), stage );
            stripe_size.height = dy_filter.process( src, Dy, cvRect(0,y,-1,delta),
                                                    cvPoint(0,0), stage );
        }
        else
        {
            delta = icvIPPFilterNextStripe( src, tempsrc, y, el_size, el_anchor );
            stripe_size.height = delta;

            if( ipp_sobel_vert )
            {
                IPPI_CALL( ipp_sobel_vert( shifted_ptr, temp_step,
                                           Dx->data.ptr, d_step, stripe_size,
                                           aperture_size*10 + aperture_size ));
                IPPI_CALL( ipp_sobel_horiz( shifted_ptr, temp_step,
                                            Dy->data.ptr, d_step, stripe_size,
                                            aperture_size*10 + aperture_size ));
            }
            else /*if( ipp_scharr_vert )*/
            {
                IPPI_CALL( ipp_scharr_vert( shifted_ptr, temp_step,
                                            Dx->data.ptr, d_step, stripe_size ));
                IPPI_CALL( ipp_scharr_horiz( shifted_ptr, temp_step,
                                             Dy->data.ptr, d_step, stripe_size ));
            }
        }

        for( i = 0; i < stripe_size.height; i++ )
        {
            float* cov_data = (float*)(cov->data.ptr + i*cov->step);
            if( d_depth == CV_16S )
            {
                const short* dxdata = (const short*)(Dx->data.ptr + i*Dx->step);
                const short* dydata = (const short*)(Dy->data.ptr + i*Dy->step);

                for( j = 0; j < size.width; j++ )
                {
                    double dx = dxdata[j]*factorx;
                    double dy = dydata[j]*factory;

                    cov_data[j*3] = (float)(dx*dx);
                    cov_data[j*3+1] = (float)(dx*dy);
                    cov_data[j*3+2] = (float)(dy*dy);
                }
            }
            else
            {
                const float* dxdata = (const float*)(Dx->data.ptr + i*Dx->step);
                const float* dydata = (const float*)(Dy->data.ptr + i*Dy->step);

                for( j = 0; j < size.width; j++ )
                {
                    double dx = dxdata[j]*factorx;
                    double dy = dydata[j]*factory;

                    cov_data[j*3] = (float)(dx*dx);
                    cov_data[j*3+1] = (float)(dx*dy);
                    cov_data[j*3+2] = (float)(dy*dy);
                }
            }
        }

        if( y + stripe_size.height >= size.height )
            stage = stage & CV_START ? CV_START + CV_END : CV_END;

        stripe_size.height = blur_filter.process(cov,cov,
                             cvRect(0,0,-1,stripe_size.height),cvPoint(0,0),stage+CV_ISOLATED_ROI);

        if( op_type == ICV_MINEIGENVAL )
            icvCalcMinEigenVal( cov->data.fl, cov->step,
                                (float*)(eigenv->data.ptr + dst_y*eigenv->step), eigenv->step,
                                stripe_size, sqrt_buf );
        else if( op_type == ICV_HARRIS )
            icvCalcHarris( cov->data.fl, cov->step,
                           (float*)(eigenv->data.ptr + dst_y*eigenv->step), eigenv->step,
                           stripe_size, sqrt_buf, k );
        else if( op_type == ICV_EIGENVALSVECS )
            icvCalcEigenValsVecs( cov->data.fl, cov->step,
                                  (float*)(eigenv->data.ptr + dst_y*eigenv->step), eigenv->step,
                                  stripe_size, sqrt_buf );

        dst_y += stripe_size.height;
        stage = CV_MIDDLE;
    }

    __END__;

    cvReleaseMat( &Dx );
    cvReleaseMat( &Dy );
    cvReleaseMat( &cov );
    cvReleaseMat( &sqrt_buf );
    cvReleaseMat( &tempsrc );
}
Exemple #15
0
CV_IMPL  CvBox2D
cvMinAreaRect2( const CvArr* array, CvMemStorage* storage )
{
    CvMemStorage* temp_storage = 0;
    CvBox2D box;
    CvPoint2D32f* points = 0;
    
    CV_FUNCNAME( "cvMinAreaRect2" );

    memset(&box, 0, sizeof(box));

    __BEGIN__;

    int i, n;
    CvSeqReader reader;
    CvContour contour_header;
    CvSeqBlock block;
    CvSeq* ptseq = (CvSeq*)array;
    CvPoint2D32f out[3];

    if( CV_IS_SEQ(ptseq) )
    {
        if( !CV_IS_SEQ_POINT_SET(ptseq) &&
            (CV_SEQ_KIND(ptseq) != CV_SEQ_KIND_CURVE || !CV_IS_SEQ_CONVEX(ptseq) ||
            CV_SEQ_ELTYPE(ptseq) != CV_SEQ_ELTYPE_PPOINT ))
            CV_ERROR( CV_StsUnsupportedFormat,
                "Input sequence must consist of 2d points or pointers to 2d points" );
        if( !storage )
            storage = ptseq->storage;
    }
    else
    {
        CV_CALL( ptseq = cvPointSeqFromMat(
            CV_SEQ_KIND_GENERIC, array, &contour_header, &block ));
    }

    if( storage )
    {
        CV_CALL( temp_storage = cvCreateChildMemStorage( storage ));
    }
    else
    {
        CV_CALL( temp_storage = cvCreateMemStorage(1 << 10));
    }

    if( !CV_IS_SEQ_CONVEX( ptseq ))
    {
        CV_CALL( ptseq = cvConvexHull2( ptseq, temp_storage, CV_CLOCKWISE, 1 ));
    }
    else if( !CV_IS_SEQ_POINT_SET( ptseq ))
    {
        CvSeqWriter writer;
        
        if( !CV_IS_SEQ(ptseq->v_prev) || !CV_IS_SEQ_POINT_SET(ptseq->v_prev))
            CV_ERROR( CV_StsBadArg,
            "Convex hull must have valid pointer to point sequence stored in v_prev" );
        cvStartReadSeq( ptseq, &reader );
        cvStartWriteSeq( CV_SEQ_KIND_CURVE|CV_SEQ_FLAG_CONVEX|CV_SEQ_ELTYPE(ptseq->v_prev),
                         sizeof(CvContour), CV_ELEM_SIZE(ptseq->v_prev->flags),
                         temp_storage, &writer );
            
        for( i = 0; i < ptseq->total; i++ )
        {
            CvPoint pt = **(CvPoint**)(reader.ptr);
            CV_WRITE_SEQ_ELEM( pt, writer );
        }

        ptseq = cvEndWriteSeq( &writer );
    }

    n = ptseq->total;

    CV_CALL( points = (CvPoint2D32f*)cvAlloc( n*sizeof(points[0]) ));
    cvStartReadSeq( ptseq, &reader );

    if( CV_SEQ_ELTYPE( ptseq ) == CV_32SC2 )
    {
        for( i = 0; i < n; i++ )
        {
            CvPoint pt;
            CV_READ_SEQ_ELEM( pt, reader );
            points[i].x = (float)pt.x;
            points[i].y = (float)pt.y;
        }
    }
    else
    {
        for( i = 0; i < n; i++ )
        {
            CV_READ_SEQ_ELEM( points[i], reader );
        }
    }
    
    if( n > 2 )
    {
        icvRotatingCalipers( points, n, CV_CALIPERS_MINAREARECT, (float*)out );
        box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f;
        box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f;
        box.size.height = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y);
        box.size.width = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y);
        box.angle = (float)atan2( -(double)out[1].y, (double)out[1].x );
    }
    else if( n == 2 )
    {
        box.center.x = (points[0].x + points[1].x)*0.5f;
        box.center.y = (points[0].y + points[1].y)*0.5f;
        double dx = points[1].x - points[0].x;
        double dy = points[1].y - points[0].y;
        box.size.height = (float)sqrt(dx*dx + dy*dy);
        box.size.width = 0;
        box.angle = (float)atan2( -dy, dx );
    }
    else
    {
        if( n == 1 )
            box.center = points[0];
    }

    box.angle = (float)(box.angle*180/CV_PI);

    __END__; 

    cvReleaseMemStorage( &temp_storage );
    cvFree( &points );

    return box;
}
Exemple #16
0
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
                Size corrsize, int ctype,
                Point anchor, double delta, int borderType )
{
    const double blockScale = 4.5;
    const int minBlockSize = 256;
    std::vector<uchar> buf;

    Mat templ = _templ;
    int depth = img.depth(), cn = img.channels();
    int tdepth = templ.depth(), tcn = templ.channels();
    int cdepth = CV_MAT_DEPTH(ctype), ccn = CV_MAT_CN(ctype);

    CV_Assert( img.dims <= 2 && templ.dims <= 2 && corr.dims <= 2 );

    if( depth != tdepth && tdepth != std::max(CV_32F, depth) )
    {
        _templ.convertTo(templ, std::max(CV_32F, depth));
        tdepth = templ.depth();
    }

    CV_Assert( depth == tdepth || tdepth == CV_32F);
    CV_Assert( corrsize.height <= img.rows + templ.rows - 1 &&
               corrsize.width <= img.cols + templ.cols - 1 );

    CV_Assert( ccn == 1 || delta == 0 );

    corr.create(corrsize, ctype);

    int maxDepth = depth > CV_8S ? CV_64F : std::max(std::max(CV_32F, tdepth), cdepth);
    Size blocksize, dftsize;

    blocksize.width = cvRound(templ.cols*blockScale);
    blocksize.width = std::max( blocksize.width, minBlockSize - templ.cols + 1 );
    blocksize.width = std::min( blocksize.width, corr.cols );
    blocksize.height = cvRound(templ.rows*blockScale);
    blocksize.height = std::max( blocksize.height, minBlockSize - templ.rows + 1 );
    blocksize.height = std::min( blocksize.height, corr.rows );

    dftsize.width = std::max(getOptimalDFTSize(blocksize.width + templ.cols - 1), 2);
    dftsize.height = getOptimalDFTSize(blocksize.height + templ.rows - 1);
    if( dftsize.width <= 0 || dftsize.height <= 0 )
        CV_Error( CV_StsOutOfRange, "the input arrays are too big" );

    // recompute block size
    blocksize.width = dftsize.width - templ.cols + 1;
    blocksize.width = MIN( blocksize.width, corr.cols );
    blocksize.height = dftsize.height - templ.rows + 1;
    blocksize.height = MIN( blocksize.height, corr.rows );

    Mat dftTempl( dftsize.height*tcn, dftsize.width, maxDepth );
    Mat dftImg( dftsize, maxDepth );

    int i, k, bufSize = 0;
    if( tcn > 1 && tdepth != maxDepth )
        bufSize = templ.cols*templ.rows*CV_ELEM_SIZE(tdepth);

    if( cn > 1 && depth != maxDepth )
        bufSize = std::max( bufSize, (blocksize.width + templ.cols - 1)*
            (blocksize.height + templ.rows - 1)*CV_ELEM_SIZE(depth));

    if( (ccn > 1 || cn > 1) && cdepth != maxDepth )
        bufSize = std::max( bufSize, blocksize.width*blocksize.height*CV_ELEM_SIZE(cdepth));

    buf.resize(bufSize);

    // compute DFT of each template plane
    for( k = 0; k < tcn; k++ )
    {
        int yofs = k*dftsize.height;
        Mat src = templ;
        Mat dst(dftTempl, Rect(0, yofs, dftsize.width, dftsize.height));
        Mat dst1(dftTempl, Rect(0, yofs, templ.cols, templ.rows));

        if( tcn > 1 )
        {
            src = tdepth == maxDepth ? dst1 : Mat(templ.size(), tdepth, &buf[0]);
            int pairs[] = {k, 0};
            mixChannels(&templ, 1, &src, 1, pairs, 1);
        }

        if( dst1.data != src.data )
            src.convertTo(dst1, dst1.depth());

        if( dst.cols > templ.cols )
        {
            Mat part(dst, Range(0, templ.rows), Range(templ.cols, dst.cols));
            part = Scalar::all(0);
        }
        dft(dst, dst, 0, templ.rows);
    }

    int tileCountX = (corr.cols + blocksize.width - 1)/blocksize.width;
    int tileCountY = (corr.rows + blocksize.height - 1)/blocksize.height;
    int tileCount = tileCountX * tileCountY;

    Size wholeSize = img.size();
    Point roiofs(0,0);
    Mat img0 = img;

    if( !(borderType & BORDER_ISOLATED) )
    {
        img.locateROI(wholeSize, roiofs);
        img0.adjustROI(roiofs.y, wholeSize.height-img.rows-roiofs.y,
                       roiofs.x, wholeSize.width-img.cols-roiofs.x);
    }
    borderType |= BORDER_ISOLATED;

    // calculate correlation by blocks
    for( i = 0; i < tileCount; i++ )
    {
        int x = (i%tileCountX)*blocksize.width;
        int y = (i/tileCountX)*blocksize.height;

        Size bsz(std::min(blocksize.width, corr.cols - x),
                 std::min(blocksize.height, corr.rows - y));
        Size dsz(bsz.width + templ.cols - 1, bsz.height + templ.rows - 1);
        int x0 = x - anchor.x + roiofs.x, y0 = y - anchor.y + roiofs.y;
        int x1 = std::max(0, x0), y1 = std::max(0, y0);
        int x2 = std::min(img0.cols, x0 + dsz.width);
        int y2 = std::min(img0.rows, y0 + dsz.height);
        Mat src0(img0, Range(y1, y2), Range(x1, x2));
        Mat dst(dftImg, Rect(0, 0, dsz.width, dsz.height));
        Mat dst1(dftImg, Rect(x1-x0, y1-y0, x2-x1, y2-y1));
        Mat cdst(corr, Rect(x, y, bsz.width, bsz.height));

        for( k = 0; k < cn; k++ )
        {
            Mat src = src0;
            dftImg = Scalar::all(0);

            if( cn > 1 )
            {
                src = depth == maxDepth ? dst1 : Mat(y2-y1, x2-x1, depth, &buf[0]);
                int pairs[] = {k, 0};
                mixChannels(&src0, 1, &src, 1, pairs, 1);
            }

            if( dst1.data != src.data )
                src.convertTo(dst1, dst1.depth());

            if( x2 - x1 < dsz.width || y2 - y1 < dsz.height )
                copyMakeBorder(dst1, dst, y1-y0, dst.rows-dst1.rows-(y1-y0),
                               x1-x0, dst.cols-dst1.cols-(x1-x0), borderType);

            dft( dftImg, dftImg, 0, dsz.height );
            Mat dftTempl1(dftTempl, Rect(0, tcn > 1 ? k*dftsize.height : 0,
                                         dftsize.width, dftsize.height));
            mulSpectrums(dftImg, dftTempl1, dftImg, 0, true);
            dft( dftImg, dftImg, DFT_INVERSE + DFT_SCALE, bsz.height );

            src = dftImg(Rect(0, 0, bsz.width, bsz.height));

            if( ccn > 1 )
            {
                if( cdepth != maxDepth )
                {
                    Mat plane(bsz, cdepth, &buf[0]);
                    src.convertTo(plane, cdepth, 1, delta);
                    src = plane;
                }
                int pairs[] = {0, k};
                mixChannels(&src, 1, &cdst, 1, pairs, 1);
            }
            else
            {
                if( k == 0 )
                    src.convertTo(cdst, cdepth, 1, delta);
                else
                {
                    if( maxDepth != cdepth )
                    {
                        Mat plane(bsz, cdepth, &buf[0]);
                        src.convertTo(plane, cdepth);
                        src = plane;
                    }
                    add(src, cdst, cdst);
                }
            }
        }
    }
}
void
icvCrossCorr( const CvArr* _img, const CvArr* _templ, CvArr* _corr,
              CvPoint anchor, double delta, int borderType )
{
    // disable OpenMP in the case of Visual Studio,
    // otherwise the performance drops significantly
#undef USE_OPENMP
#if !defined _MSC_VER || defined CV_ICC
    #define USE_OPENMP 1
#endif

    const double block_scale = 4.5;
    const int min_block_size = 256;
    cv::Ptr<CvMat> dft_img[CV_MAX_THREADS];
    cv::Ptr<CvMat> dft_templ;
    std::vector<uchar> buf[CV_MAX_THREADS];
    int k, num_threads = 0;
    
    CvMat istub, *img = (CvMat*)_img;
    CvMat tstub, *templ = (CvMat*)_templ;
    CvMat cstub, *corr = (CvMat*)_corr;
    CvSize dftsize, blocksize;
    int depth, templ_depth, corr_depth, max_depth = CV_32F,
        cn, templ_cn, corr_cn, buf_size = 0,
        tile_count_x, tile_count_y, tile_count;

    img = cvGetMat( img, &istub );
    templ = cvGetMat( templ, &tstub );
    corr = cvGetMat( corr, &cstub );

    if( CV_MAT_DEPTH( img->type ) != CV_8U &&
        CV_MAT_DEPTH( img->type ) != CV_16U &&
        CV_MAT_DEPTH( img->type ) != CV_32F &&
        CV_MAT_DEPTH( img->type ) != CV_64F )
        CV_Error( CV_StsUnsupportedFormat,
        "The function supports only 8u, 16u and 32f data types" );

    if( !CV_ARE_DEPTHS_EQ( img, templ ) && CV_MAT_DEPTH( templ->type ) != CV_32F )
        CV_Error( CV_StsUnsupportedFormat,
        "Template (kernel) must be of the same depth as the input image, or be 32f" );
    
    if( !CV_ARE_DEPTHS_EQ( img, corr ) && CV_MAT_DEPTH( corr->type ) != CV_32F &&
        CV_MAT_DEPTH( corr->type ) != CV_64F )
        CV_Error( CV_StsUnsupportedFormat,
        "The output image must have the same depth as the input image, or be 32f/64f" );

    if( (!CV_ARE_CNS_EQ( img, corr ) || CV_MAT_CN(templ->type) > 1) &&
        (CV_MAT_CN( corr->type ) > 1 || !CV_ARE_CNS_EQ( img, templ)) )
        CV_Error( CV_StsUnsupportedFormat,
        "The output must have the same number of channels as the input (when the template has 1 channel), "
        "or the output must have 1 channel when the input and the template have the same number of channels" );

    depth = CV_MAT_DEPTH(img->type);
    cn = CV_MAT_CN(img->type);
    templ_depth = CV_MAT_DEPTH(templ->type);
    templ_cn = CV_MAT_CN(templ->type);
    corr_depth = CV_MAT_DEPTH(corr->type);
    corr_cn = CV_MAT_CN(corr->type);

    CV_Assert( corr_cn == 1 || delta == 0 );

    max_depth = MAX( max_depth, templ_depth );
    max_depth = MAX( max_depth, depth );
    max_depth = MAX( max_depth, corr_depth );
    if( depth > CV_8U )
        max_depth = CV_64F;

    /*if( img->cols < templ->cols || img->rows < templ->rows )
        CV_Error( CV_StsUnmatchedSizes,
        "Such a combination of image and template/filter size is not supported" );*/

    if( corr->rows > img->rows + templ->rows - 1 ||
        corr->cols > img->cols + templ->cols - 1 )
        CV_Error( CV_StsUnmatchedSizes,
        "output image should not be greater than (W + w - 1)x(H + h - 1)" );

    blocksize.width = cvRound(templ->cols*block_scale);
    blocksize.width = MAX( blocksize.width, min_block_size - templ->cols + 1 );
    blocksize.width = MIN( blocksize.width, corr->cols );
    blocksize.height = cvRound(templ->rows*block_scale);
    blocksize.height = MAX( blocksize.height, min_block_size - templ->rows + 1 );
    blocksize.height = MIN( blocksize.height, corr->rows );

    dftsize.width = cvGetOptimalDFTSize(blocksize.width + templ->cols - 1);
    if( dftsize.width == 1 )
        dftsize.width = 2;
    dftsize.height = cvGetOptimalDFTSize(blocksize.height + templ->rows - 1);
    if( dftsize.width <= 0 || dftsize.height <= 0 )
        CV_Error( CV_StsOutOfRange, "the input arrays are too big" );

    // recompute block size
    blocksize.width = dftsize.width - templ->cols + 1;
    blocksize.width = MIN( blocksize.width, corr->cols );
    blocksize.height = dftsize.height - templ->rows + 1;
    blocksize.height = MIN( blocksize.height, corr->rows );

    dft_templ = cvCreateMat( dftsize.height*templ_cn, dftsize.width, max_depth );

#ifdef USE_OPENMP
    num_threads = cvGetNumThreads();
#else
    num_threads = 1;
#endif

    for( k = 0; k < num_threads; k++ )
        dft_img[k] = cvCreateMat( dftsize.height, dftsize.width, max_depth );

    if( templ_cn > 1 && templ_depth != max_depth )
        buf_size = templ->cols*templ->rows*CV_ELEM_SIZE(templ_depth);

    if( cn > 1 && depth != max_depth )
        buf_size = MAX( buf_size, (blocksize.width + templ->cols - 1)*
            (blocksize.height + templ->rows - 1)*CV_ELEM_SIZE(depth));

    if( (corr_cn > 1 || cn > 1) && corr_depth != max_depth )
        buf_size = MAX( buf_size, blocksize.width*blocksize.height*CV_ELEM_SIZE(corr_depth));

    if( buf_size > 0 )
    {
        for( k = 0; k < num_threads; k++ )
            buf[k].resize(buf_size);
    }

    // compute DFT of each template plane
    for( k = 0; k < templ_cn; k++ )
    {
        CvMat dstub, *src, *dst, temp;
        CvMat* planes[] = { 0, 0, 0, 0 };
        int yofs = k*dftsize.height;

        src = templ;
        dst = cvGetSubRect( dft_templ, &dstub, cvRect(0,yofs,templ->cols,templ->rows));
    
        if( templ_cn > 1 )
        {
            planes[k] = templ_depth == max_depth ? dst :
                cvInitMatHeader( &temp, templ->rows, templ->cols, templ_depth, &buf[0][0] );
            cvSplit( templ, planes[0], planes[1], planes[2], planes[3] );
            src = planes[k];
            planes[k] = 0;
        }

        if( dst != src )
            cvConvert( src, dst );

        if( dft_templ->cols > templ->cols )
        {
            cvGetSubRect( dft_templ, dst, cvRect(templ->cols, yofs,
                          dft_templ->cols - templ->cols, templ->rows) );
            cvZero( dst );
        }
        cvGetSubRect( dft_templ, dst, cvRect(0,yofs,dftsize.width,dftsize.height) );
        cvDFT( dst, dst, CV_DXT_FORWARD + CV_DXT_SCALE, templ->rows );
    }

    tile_count_x = (corr->cols + blocksize.width - 1)/blocksize.width;
    tile_count_y = (corr->rows + blocksize.height - 1)/blocksize.height;
    tile_count = tile_count_x*tile_count_y;

#if defined _OPENMP && defined USE_OPENMP
    #pragma omp parallel for num_threads(num_threads) schedule(dynamic)
#endif
    // calculate correlation by blocks
    for( k = 0; k < tile_count; k++ )
    {
#ifdef USE_OPENMP
        int thread_idx = cvGetThreadNum();
#else
        int thread_idx = 0;
#endif
        int x = (k%tile_count_x)*blocksize.width;
        int y = (k/tile_count_x)*blocksize.height;
        int i, yofs;
        CvMat sstub, dstub, *src, *dst, temp;
        CvMat* planes[] = { 0, 0, 0, 0 };
        CvMat* _dft_img = dft_img[thread_idx];
        uchar* _buf = buf_size > 0 ? &buf[thread_idx][0] : 0;
        CvSize csz = { blocksize.width, blocksize.height }, isz;
        int x0 = x - anchor.x, y0 = y - anchor.y;
        int x1 = MAX( 0, x0 ), y1 = MAX( 0, y0 ), x2, y2;
        csz.width = MIN( csz.width, corr->cols - x );
        csz.height = MIN( csz.height, corr->rows - y );
        isz.width = csz.width + templ->cols - 1;
        isz.height = csz.height + templ->rows - 1;
        x2 = MIN( img->cols, x0 + isz.width );
        y2 = MIN( img->rows, y0 + isz.height );
        
        for( i = 0; i < cn; i++ )
        {
            CvMat dstub1, *dst1;
            yofs = i*dftsize.height;

            src = cvGetSubRect( img, &sstub, cvRect(x1,y1,x2-x1,y2-y1) );
            dst = cvGetSubRect( _dft_img, &dstub,
                cvRect(0,0,isz.width,isz.height) );
            dst1 = dst;
            
            if( x2 - x1 < isz.width || y2 - y1 < isz.height )
                dst1 = cvGetSubRect( _dft_img, &dstub1,
                    cvRect( x1 - x0, y1 - y0, x2 - x1, y2 - y1 ));

            if( cn > 1 )
            {
                planes[i] = dst1;
                if( depth != max_depth )
                    planes[i] = cvInitMatHeader( &temp, y2 - y1, x2 - x1, depth, _buf );
                cvSplit( src, planes[0], planes[1], planes[2], planes[3] );
                src = planes[i];
                planes[i] = 0;
            }

            if( dst1 != src )
                cvConvert( src, dst1 );

            if( dst != dst1 )
                cvCopyMakeBorder( dst1, dst, cvPoint(x1 - x0, y1 - y0), borderType );

            if( dftsize.width > isz.width )
            {
                cvGetSubRect( _dft_img, dst, cvRect(isz.width, 0,
                      dftsize.width - isz.width,dftsize.height) );
                cvZero( dst );
            }

            cvDFT( _dft_img, _dft_img, CV_DXT_FORWARD, isz.height );
            cvGetSubRect( dft_templ, dst,
                cvRect(0,(templ_cn>1?yofs:0),dftsize.width,dftsize.height) );

            cvMulSpectrums( _dft_img, dst, _dft_img, CV_DXT_MUL_CONJ );
            cvDFT( _dft_img, _dft_img, CV_DXT_INVERSE, csz.height );

            src = cvGetSubRect( _dft_img, &sstub, cvRect(0,0,csz.width,csz.height) );
            dst = cvGetSubRect( corr, &dstub, cvRect(x,y,csz.width,csz.height) );

            if( corr_cn > 1 )
            {
                planes[i] = src;
                if( corr_depth != max_depth )
                {
                    planes[i] = cvInitMatHeader( &temp, csz.height, csz.width,
                                                 corr_depth, _buf );
                    cvConvertScale( src, planes[i], 1, delta );
                }
                cvMerge( planes[0], planes[1], planes[2], planes[3], dst );
                planes[i] = 0;                    
            }
            else
            {
                if( i == 0 )
                    cvConvertScale( src, dst, 1, delta );
                else
                {
                    if( max_depth > corr_depth )
                    {
                        cvInitMatHeader( &temp, csz.height, csz.width,
                                         corr_depth, _buf );
                        cvConvert( src, &temp );
                        src = &temp;
                    }
                    cvAcc( src, dst );
                }
            }
        }
    }
}
Exemple #18
0
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
                    double scale, double delta, int borderType )
{
    int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
    if (ddepth < 0)
        ddepth = sdepth;
    _dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );

#ifdef HAVE_TEGRA_OPTIMIZATION
    if (scale == 1.0 && delta == 0)
    {
        Mat src = _src.getMat(), dst = _dst.getMat();
        if (ksize == 1 && tegra::laplace1(src, dst, borderType))
            return;
        if (ksize == 3 && tegra::laplace3(src, dst, borderType))
            return;
        if (ksize == 5 && tegra::laplace5(src, dst, borderType))
            return;
    }
#endif

    if( ksize == 1 || ksize == 3 )
    {
        float K[2][9] =
        {
            { 0, 1, 0, 1, -4, 1, 0, 1, 0 },
            { 2, 0, 2, 0, -8, 0, 2, 0, 2 }
        };
        Mat kernel(3, 3, CV_32F, K[ksize == 3]);
        if( scale != 1 )
            kernel *= scale;
        filter2D( _src, _dst, ddepth, kernel, Point(-1, -1), delta, borderType );
    }
    else
    {
        int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
        int wdepth = sdepth == CV_8U && ksize <= 5 ? CV_16S : sdepth <= CV_32F ? CV_32F : CV_64F;
        int wtype = CV_MAKETYPE(wdepth, cn);
        Mat kd, ks;
        getSobelKernels( kd, ks, 2, 0, ksize, false, ktype );

        CV_OCL_RUN(_dst.isUMat(),
                   ocl_Laplacian5(_src, _dst, kd, ks, scale,
                                  delta, borderType, wdepth, ddepth))

        const size_t STRIPE_SIZE = 1 << 14;
        Ptr<FilterEngine> fx = createSeparableLinearFilter(stype,
            wtype, kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() );
        Ptr<FilterEngine> fy = createSeparableLinearFilter(stype,
            wtype, ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() );

        Mat src = _src.getMat(), dst = _dst.getMat();
        int y = fx->start(src), dsty = 0, dy = 0;
        fy->start(src);
        const uchar* sptr = src.data + y*src.step;

        int dy0 = std::min(std::max((int)(STRIPE_SIZE/(CV_ELEM_SIZE(stype)*src.cols)), 1), src.rows);
        Mat d2x( dy0 + kd.rows - 1, src.cols, wtype );
        Mat d2y( dy0 + kd.rows - 1, src.cols, wtype );

        for( ; dsty < src.rows; sptr += dy0*src.step, dsty += dy )
        {
            fx->proceed( sptr, (int)src.step, dy0, d2x.data, (int)d2x.step );
            dy = fy->proceed( sptr, (int)src.step, dy0, d2y.data, (int)d2y.step );
            if( dy > 0 )
            {
                Mat dstripe = dst.rowRange(dsty, dsty + dy);
                d2x.rows = d2y.rows = dy; // modify the headers, which should work
                d2x += d2y;
                d2x.convertTo( dstripe, ddepth, scale, delta );
            }
        }
    }
}
Exemple #19
0
static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
Exemple #20
0
inline
size_t GpuMat::elemSize() const
{
    return CV_ELEM_SIZE(flags);
}
CV_IMPL  void
cvSVD( CvArr* aarr, CvArr* warr, CvArr* uarr, CvArr* varr, int flags )
{
    uchar* buffer = 0;
    int local_alloc = 0;

    CV_FUNCNAME( "cvSVD" );

    __BEGIN__;

    CvMat astub, *a = (CvMat*)aarr;
    CvMat wstub, *w = (CvMat*)warr;
    CvMat ustub, *u;
    CvMat vstub, *v;
    CvMat tmat;
    uchar* tw = 0;
    int type;
    int a_buf_offset = 0, u_buf_offset = 0, buf_size, pix_size;
    int temp_u = 0, /* temporary storage for U is needed */
        t_svd; /* special case: a->rows < a->cols */
    int m, n;
    int w_rows, w_cols;
    int u_rows = 0, u_cols = 0;
    int w_is_mat = 0;

    if( !CV_IS_MAT( a ))
        CV_CALL( a = cvGetMat( a, &astub ));

    if( !CV_IS_MAT( w ))
        CV_CALL( w = cvGetMat( w, &wstub ));

    if( !CV_ARE_TYPES_EQ( a, w ))
        CV_ERROR( CV_StsUnmatchedFormats, "" );

    if( a->rows >= a->cols )
    {
        m = a->rows;
        n = a->cols;
        w_rows = w->rows;
        w_cols = w->cols;
        t_svd = 0;
    }
    else
    {
        CvArr* t;
        CV_SWAP( uarr, varr, t );

        flags = (flags & CV_SVD_U_T ? CV_SVD_V_T : 0)|
                (flags & CV_SVD_V_T ? CV_SVD_U_T : 0);
        m = a->cols;
        n = a->rows;
        w_rows = w->cols;
        w_cols = w->rows;
        t_svd = 1;
    }

    u = (CvMat*)uarr;
    v = (CvMat*)varr;

    w_is_mat = w_cols > 1 && w_rows > 1;

    if( !w_is_mat && CV_IS_MAT_CONT(w->type) && w_cols + w_rows - 1 == n )
        tw = w->data.ptr;

    if( u )
    {
        if( !CV_IS_MAT( u ))
            CV_CALL( u = cvGetMat( u, &ustub ));

        if( !(flags & CV_SVD_U_T) )
        {
            u_rows = u->rows;
            u_cols = u->cols;
        }
        else
        {
            u_rows = u->cols;
            u_cols = u->rows;
        }

        if( !CV_ARE_TYPES_EQ( a, u ))
            CV_ERROR( CV_StsUnmatchedFormats, "" );

        if( u_rows != m || (u_cols != m && u_cols != n))
            CV_ERROR( CV_StsUnmatchedSizes, !t_svd ? "U matrix has unappropriate size" :
                                                     "V matrix has unappropriate size" );
            
        temp_u = (u_rows != u_cols && !(flags & CV_SVD_U_T)) || u->data.ptr==a->data.ptr;

        if( w_is_mat && u_cols != w_rows )
            CV_ERROR( CV_StsUnmatchedSizes, !t_svd ? "U and W have incompatible sizes" :
                                                     "V and W have incompatible sizes" );
    }
    else
    {
        u = &ustub;
        u->data.ptr = 0;
        u->step = 0;
    }

    if( v )
    {
        int v_rows, v_cols;

        if( !CV_IS_MAT( v ))
            CV_CALL( v = cvGetMat( v, &vstub ));

        if( !(flags & CV_SVD_V_T) )
        {
            v_rows = v->rows;
            v_cols = v->cols;
        }
        else
        {
            v_rows = v->cols;
            v_cols = v->rows;
        }

        if( !CV_ARE_TYPES_EQ( a, v ))
            CV_ERROR( CV_StsUnmatchedFormats, "" );

        if( v_rows != n || v_cols != n )
            CV_ERROR( CV_StsUnmatchedSizes, t_svd ? "U matrix has unappropriate size" :
                                                    "V matrix has unappropriate size" );

        if( w_is_mat && w_cols != v_cols )
            CV_ERROR( CV_StsUnmatchedSizes, t_svd ? "U and W have incompatible sizes" :
                                                    "V and W have incompatible sizes" );
    }
    else
    {
        v = &vstub;
        v->data.ptr = 0;
        v->step = 0;
    }

    type = CV_MAT_TYPE( a->type );
    pix_size = CV_ELEM_SIZE(type);
    buf_size = n*2 + m;

    if( !(flags & CV_SVD_MODIFY_A) )
    {
        a_buf_offset = buf_size;
        buf_size += a->rows*a->cols;
    }

    if( temp_u )
    {
        u_buf_offset = buf_size;
        buf_size += u->rows*u->cols;
    }

    buf_size *= pix_size;

    if( buf_size <= CV_MAX_LOCAL_SIZE )
    {
        buffer = (uchar*)cvStackAlloc( buf_size );
        local_alloc = 1;
    }
    else
    {
        CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
    }
    
    if( !(flags & CV_SVD_MODIFY_A) )
    {
        cvInitMatHeader( &tmat, m, n, type,
                         buffer + a_buf_offset*pix_size );
        if( !t_svd )
            cvCopy( a, &tmat );
        else
            cvT( a, &tmat );
        a = &tmat;
    }

    if( temp_u )
    {
        cvInitMatHeader( &ustub, u_cols, u_rows, type, buffer + u_buf_offset*pix_size );
        u = &ustub;
    }

    if( !tw )
        tw = buffer + (n + m)*pix_size;

    if( type == CV_32FC1 )
    {
        icvSVD_32f( a->data.fl, a->step/sizeof(float), a->rows, a->cols,
                   (float*)tw, u->data.fl, u->step/sizeof(float), u_cols,
                   v->data.fl, v->step/sizeof(float), (float*)buffer );
    }
    else if( type == CV_64FC1 )
    {
        icvSVD_64f( a->data.db, a->step/sizeof(double), a->rows, a->cols,
                    (double*)tw, u->data.db, u->step/sizeof(double), u_cols,
                    v->data.db, v->step/sizeof(double), (double*)buffer );
    }
    else
    {
        CV_ERROR( CV_StsUnsupportedFormat, "" );
    }

    if( tw != w->data.ptr )
    {
        int shift = w->cols != 1;
        cvSetZero( w );
        if( type == CV_32FC1 )
            for( int i = 0; i < n; i++ )
                ((float*)(w->data.ptr + i*w->step))[i*shift] = ((float*)tw)[i];
        else
            for( int i = 0; i < n; i++ )
                ((double*)(w->data.ptr + i*w->step))[i*shift] = ((double*)tw)[i];
    }

    if( uarr )
    {
        if( !(flags & CV_SVD_U_T))
            cvT( u, uarr );
        else if( temp_u )
            cvCopy( u, uarr );
        /*CV_CHECK_NANS( uarr );*/
    }

    if( varr )
    {
        if( !(flags & CV_SVD_V_T))
            cvT( v, varr );
        /*CV_CHECK_NANS( varr );*/
    }

    CV_CHECK_NANS( w );

    __END__;

    if( buffer && !local_alloc )
        cvFree( &buffer );
}
Exemple #22
0
 int elemSize() const { return CV_ELEM_SIZE(type_); }
CV_IMPL void
cvFilter2D( const CvArr* _src, CvArr* _dst, const CvMat* _kernel, CvPoint anchor )
{
    // below that approximate size OpenCV is faster
    const int ipp_lower_limit = 20;
    
    static CvFuncTable filter_tab;
    static int inittab = 0;
    CvFilterState *state = 0;
    float* kernel_data = 0;
    int local_alloc = 1;
    CvMat* temp = 0;

    CV_FUNCNAME( "cvFilter2D" );

    __BEGIN__;

    CvFilterFunc func = 0;
    int coi1 = 0, coi2 = 0;
    CvMat srcstub, *src = (CvMat*)_src;
    CvMat dststub, *dst = (CvMat*)_dst;
    CvSize size;
    int type, depth;
    int src_step, dst_step;
    CvMat kernel_hdr;
    const CvMat* kernel = _kernel;

    if( !inittab )
    {
        icvInitFilterTab( &filter_tab );
        inittab = 1;
    }

    CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
    CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));

    if( coi1 != 0 || coi2 != 0 )
        CV_ERROR( CV_BadCOI, "" );

    type = CV_MAT_TYPE( src->type );

    if( !CV_ARE_SIZES_EQ( src, dst ))
        CV_ERROR( CV_StsUnmatchedSizes, "" );

    if( !CV_ARE_TYPES_EQ( src, dst ))
        CV_ERROR( CV_StsUnmatchedFormats, "" );

    if( !CV_IS_MAT(kernel) ||
        (CV_MAT_TYPE(kernel->type) != CV_32F &&
        CV_MAT_TYPE(kernel->type) != CV_64F ))
        CV_ERROR( CV_StsBadArg, "kernel must be single-channel floating-point matrix" );

    if( anchor.x == -1 && anchor.y == -1 )
        anchor = cvPoint(kernel->cols/2,kernel->rows/2);

    if( (unsigned)anchor.x >= (unsigned)kernel->cols ||
        (unsigned)anchor.y >= (unsigned)kernel->rows )
        CV_ERROR( CV_StsOutOfRange, "anchor point is out of kernel" );

    if( CV_MAT_TYPE(kernel->type) != CV_32FC1 || !CV_IS_MAT_CONT(kernel->type) || icvFilter_8u_C1R_p )
    {
        int sz = kernel->rows*kernel->cols*sizeof(kernel_data[0]);
        if( sz < CV_MAX_LOCAL_SIZE )
            kernel_data = (float*)cvStackAlloc( sz );
        else
        {
            CV_CALL( kernel_data = (float*)cvAlloc( sz ));
            local_alloc = 0;
        }
        kernel_hdr = cvMat( kernel->rows, kernel->cols, CV_32F, kernel_data );
        if( CV_MAT_TYPE(kernel->type) == CV_32FC1 )
            cvCopy( kernel, &kernel_hdr );
        else
            cvConvertScale( kernel, &kernel_hdr, 1, 0 );
        kernel = &kernel_hdr;
    }

    size = cvGetMatSize( src );
    depth = CV_MAT_DEPTH(type);
    src_step = src->step;
    dst_step = dst->step ? dst->step : CV_STUB_STEP;

    if( icvFilter_8u_C1R_p && (src->rows >= ipp_lower_limit || src->cols >= ipp_lower_limit) )
    {
        CvFilterIPPFunc ipp_func = 
                type == CV_8UC1 ? (CvFilterIPPFunc)icvFilter_8u_C1R_p :
                type == CV_8UC3 ? (CvFilterIPPFunc)icvFilter_8u_C3R_p :
                type == CV_8UC4 ? (CvFilterIPPFunc)icvFilter_8u_C4R_p :
                type == CV_16SC1 ? (CvFilterIPPFunc)icvFilter_16s_C1R_p :
                type == CV_16SC3 ? (CvFilterIPPFunc)icvFilter_16s_C3R_p :
                type == CV_16SC4 ? (CvFilterIPPFunc)icvFilter_16s_C4R_p :
                type == CV_32FC1 ? (CvFilterIPPFunc)icvFilter_32f_C1R_p :
                type == CV_32FC3 ? (CvFilterIPPFunc)icvFilter_32f_C3R_p :
                type == CV_32FC4 ? (CvFilterIPPFunc)icvFilter_32f_C4R_p : 0;
        
        if( ipp_func )
        {
            CvSize el_size = { kernel->cols, kernel->rows };
            CvPoint el_anchor = { el_size.width - anchor.x - 1, el_size.height - anchor.y - 1 };
            int stripe_size = 1 << 16; // the optimal value may depend on CPU cache,
                                       // overhead of current IPP code etc.
            const uchar* shifted_ptr;
            int i, j, y, dy = 0;
            int temp_step;

            // mirror the kernel around the center
            for( i = 0; i < (el_size.height+1)/2; i++ )
            {
                float* top_row = kernel->data.fl + el_size.width*i;
                float* bottom_row = kernel->data.fl + el_size.width*(el_size.height - i - 1);

                for( j = 0; j < (el_size.width+1)/2; j++ )
                {
                    float a = top_row[j], b = top_row[el_size.width - j - 1];
                    float c = bottom_row[j], d = bottom_row[el_size.width - j - 1];
                    top_row[j] = d;
                    top_row[el_size.width - j - 1] = c;
                    bottom_row[j] = b;
                    bottom_row[el_size.width - j - 1] = a;
                }
            }

            CV_CALL( temp = icvIPPFilterInit( src, stripe_size, el_size ));
            
            shifted_ptr = temp->data.ptr +
                anchor.y*temp->step + anchor.x*CV_ELEM_SIZE(type);
            temp_step = temp->step ? temp->step : CV_STUB_STEP;

            for( y = 0; y < src->rows; y += dy )
            {
                dy = icvIPPFilterNextStripe( src, temp, y, el_size, anchor );
                IPPI_CALL( ipp_func( shifted_ptr, temp_step,
                    dst->data.ptr + y*dst_step, dst_step, cvSize(src->cols, dy),
                    kernel->data.fl, el_size, el_anchor ));
            }
            EXIT;
        }
    }

    CV_CALL( state = icvFilterInitAlloc( src->cols, cv32f, CV_MAT_CN(type),
                                   cvSize(kernel->cols, kernel->rows), anchor,
                                   kernel->data.ptr, ICV_GENERIC_KERNEL ));

    if( CV_MAT_CN(type) == 2 )
        CV_ERROR( CV_BadNumChannels, "Unsupported number of channels" );

    func = (CvFilterFunc)(filter_tab.fn_2d[depth]);

    if( !func )
        CV_ERROR( CV_StsUnsupportedFormat, "" );

    if( size.height == 1 )
        src_step = dst_step = CV_STUB_STEP;

    IPPI_CALL( func( src->data.ptr, src_step, dst->data.ptr,
                     dst_step, &size, state, 0 ));

    __END__;

    cvReleaseMat( &temp );
    icvFilterFree( &state );
    if( !local_alloc )
        cvFree( (void**)&kernel_data );
}
int icvIPPSepFilter( const CvMat* src, CvMat* dst, const CvMat* kernelX,
                     const CvMat* kernelY, CvPoint anchor )
{
    int result = 0;
    
    CvMat* top_bottom = 0;
    CvMat* vout_hin = 0;
    CvMat* dst_buf = 0;
    
    CV_FUNCNAME( "icvIPPSepFilter" );

    __BEGIN__;

    CvSize ksize;
    CvPoint el_anchor;
    CvSize size;
    int type, depth, pix_size;
    int i, x, y, dy = 0, prev_dy = 0, max_dy;
    CvMat vout;
    CvCopyNonConstBorderFunc copy_border_func;
    CvIPPSepFilterFunc x_func = 0, y_func = 0;
    int src_step, top_bottom_step;
    float *kx, *ky;
    int align, stripe_size;

    if( !icvFilterRow_8u_C1R_p )
        EXIT;

    if( !CV_ARE_TYPES_EQ( src, dst ) || !CV_ARE_SIZES_EQ( src, dst ) ||
        !CV_IS_MAT_CONT(kernelX->type & kernelY->type) ||
        CV_MAT_TYPE(kernelX->type) != CV_32FC1 ||
        CV_MAT_TYPE(kernelY->type) != CV_32FC1 ||
        kernelX->cols != 1 && kernelX->rows != 1 ||
        kernelY->cols != 1 && kernelY->rows != 1 ||
        (unsigned)anchor.x >= (unsigned)(kernelX->cols + kernelX->rows - 1) ||
        (unsigned)anchor.y >= (unsigned)(kernelY->cols + kernelY->rows - 1) )
        CV_ERROR( CV_StsError, "Internal Error: incorrect parameters" );

    ksize.width = kernelX->cols + kernelX->rows - 1;
    ksize.height = kernelY->cols + kernelY->rows - 1;

    /*if( ksize.width <= 5 && ksize.height <= 5 )
    {
        float* ker = (float*)cvStackAlloc( ksize.width*ksize.height*sizeof(ker[0]));
        CvMat kernel = cvMat( ksize.height, ksize.width, CV_32F, ker );
        for( y = 0, i = 0; y < ksize.height; y++ )
            for( x = 0; x < ksize.width; x++, i++ )
                ker[i] = kernelY->data.fl[y]*kernelX->data.fl[x];

        CV_CALL( cvFilter2D( src, dst, &kernel, anchor ));
        EXIT;
    }*/

    type = CV_MAT_TYPE(src->type);
    depth = CV_MAT_DEPTH(type);
    pix_size = CV_ELEM_SIZE(type);

    if( type == CV_8UC1 )
        x_func = icvFilterRow_8u_C1R_p, y_func = icvFilterColumn_8u_C1R_p;
    else if( type == CV_8UC3 )
        x_func = icvFilterRow_8u_C3R_p, y_func = icvFilterColumn_8u_C3R_p;
    else if( type == CV_8UC4 )
        x_func = icvFilterRow_8u_C4R_p, y_func = icvFilterColumn_8u_C4R_p;
    else if( type == CV_16SC1 )
        x_func = icvFilterRow_16s_C1R_p, y_func = icvFilterColumn_16s_C1R_p;
    else if( type == CV_16SC3 )
        x_func = icvFilterRow_16s_C3R_p, y_func = icvFilterColumn_16s_C3R_p;
    else if( type == CV_16SC4 )
        x_func = icvFilterRow_16s_C4R_p, y_func = icvFilterColumn_16s_C4R_p;
    else if( type == CV_32FC1 )
        x_func = icvFilterRow_32f_C1R_p, y_func = icvFilterColumn_32f_C1R_p;
    else if( type == CV_32FC3 )
        x_func = icvFilterRow_32f_C3R_p, y_func = icvFilterColumn_32f_C3R_p;
    else if( type == CV_32FC4 )
        x_func = icvFilterRow_32f_C4R_p, y_func = icvFilterColumn_32f_C4R_p;
    else
        EXIT;

    size = cvGetMatSize(src);
    stripe_size = src->data.ptr == dst->data.ptr ? 1 << 15 : 1 << 16;
    max_dy = MAX( ksize.height - 1, stripe_size/(size.width + ksize.width - 1));
    max_dy = MIN( max_dy, size.height + ksize.height - 1 );
    
    align = 8/CV_ELEM_SIZE(depth);

    CV_CALL( top_bottom = cvCreateMat( ksize.height*2, cvAlign(size.width,align), type ));

    CV_CALL( vout_hin = cvCreateMat( max_dy + ksize.height,
        cvAlign(size.width + ksize.width - 1, align), type ));
    
    if( src->data.ptr == dst->data.ptr && size.height )
        CV_CALL( dst_buf = cvCreateMat( max_dy + ksize.height,
            cvAlign(size.width, align), type ));

    kx = (float*)cvStackAlloc( ksize.width*sizeof(kx[0]) );
    ky = (float*)cvStackAlloc( ksize.height*sizeof(ky[0]) );

    // mirror the kernels
    for( i = 0; i < ksize.width; i++ )
        kx[i] = kernelX->data.fl[ksize.width - i - 1];

    for( i = 0; i < ksize.height; i++ )
        ky[i] = kernelY->data.fl[ksize.height - i - 1];

    el_anchor = cvPoint( ksize.width - anchor.x - 1, ksize.height - anchor.y - 1 );

    cvGetCols( vout_hin, &vout, anchor.x, anchor.x + size.width );
    copy_border_func = icvGetCopyNonConstBorderFunc( pix_size, IPL_BORDER_REPLICATE );

    src_step = src->step ? src->step : CV_STUB_STEP;
    top_bottom_step = top_bottom->step ? top_bottom->step : CV_STUB_STEP;
    vout.step = vout.step ? vout.step : CV_STUB_STEP;

    for( y = 0; y < size.height; y += dy )
    {
        const CvMat *vin = src, *hout = dst;
        int src_y = y, dst_y = y;
        dy = MIN( max_dy, size.height - (ksize.height - anchor.y - 1) - y );

        if( y < anchor.y || dy < anchor.y )
        {
            int ay = anchor.y;
            CvSize src_stripe_size = size;
            
            if( y < anchor.y )
            {
                src_y = 0;
                dy = MIN( anchor.y, size.height );
                src_stripe_size.height = MIN( dy + ksize.height - anchor.y - 1, size.height );
            }
            else
            {
                src_y = MAX( y - anchor.y, 0 );
                dy = size.height - y;
                src_stripe_size.height = MIN( dy + anchor.y, size.height );
                ay = MAX( anchor.y - y, 0 );
            }

            copy_border_func( src->data.ptr + src_y*src_step, src_step, src_stripe_size,
                              top_bottom->data.ptr, top_bottom_step,
                              cvSize(size.width, dy + ksize.height - 1),
                              ay, 0 );
            vin = top_bottom;
            src_y = anchor.y;            
        }

        // do vertical convolution
        IPPI_CALL( y_func( vin->data.ptr + src_y*vin->step, vin->step ? vin->step : CV_STUB_STEP,
                           vout.data.ptr, vout.step, cvSize(size.width, dy),
                           ky, ksize.height, el_anchor.y ));

        // now it's time to copy the previously processed stripe to the input/output image
        if( src->data.ptr == dst->data.ptr )
        {
            for( i = 0; i < prev_dy; i++ )
                memcpy( dst->data.ptr + (y - prev_dy + i)*dst->step,
                        dst_buf->data.ptr + i*dst_buf->step, size.width*pix_size );
            if( y + dy < size.height )
            {
                hout = dst_buf;
                dst_y = 0;
            }
        }

        // create a border for every line by replicating the left-most/right-most elements
        for( i = 0; i < dy; i++ )
        {
            uchar* ptr = vout.data.ptr + i*vout.step;
            for( x = -1; x >= -anchor.x*pix_size; x-- )
                ptr[x] = ptr[x + pix_size];
            for( x = size.width*pix_size; x < (size.width+ksize.width-anchor.x-1)*pix_size; x++ )
                ptr[x] = ptr[x - pix_size];
        }

        // do horizontal convolution
        IPPI_CALL( x_func( vout.data.ptr, vout.step, hout->data.ptr + dst_y*hout->step,
                           hout->step ? hout->step : CV_STUB_STEP,
                           cvSize(size.width, dy), kx, ksize.width, el_anchor.x ));
        prev_dy = dy;
    }

    result = 1;

    __END__;

    cvReleaseMat( &vout_hin );
    cvReleaseMat( &dst_buf );
    cvReleaseMat( &top_bottom );

    return result;
}
Exemple #25
0
/* it must have more than 3 points  */
CV_IMPL CvSeq*
cvConvexityDefects( const CvArr* array,
                    const CvArr* hullarray,
                    CvMemStorage* storage )
{
    CvSeq* defects = 0;

    CV_FUNCNAME( "cvConvexityDefects" );

    __BEGIN__;

    int i, index;
    CvPoint* hull_cur;

    /* is orientation of hull different from contour one */
    int rev_orientation;

    CvContour contour_header;
    union { CvContour c; CvSeq s; } hull_header;
    CvSeqBlock block, hullblock;
    CvSeq *ptseq = (CvSeq*)array, *hull = (CvSeq*)hullarray;

    CvSeqReader hull_reader;
    CvSeqReader ptseq_reader;
    CvSeqWriter writer;
    int is_index;

    if( CV_IS_SEQ( ptseq ))
    {
        if( !CV_IS_SEQ_POINT_SET( ptseq ))
            CV_ERROR( CV_StsUnsupportedFormat,
                "Input sequence is not a sequence of points" );
        if( !storage )
            storage = ptseq->storage;
    }
    else
    {
        CV_CALL( ptseq = cvPointSeqFromMat(
            CV_SEQ_KIND_GENERIC, array, &contour_header, &block ));
    }

    if( CV_SEQ_ELTYPE( ptseq ) != CV_32SC2 )
        CV_ERROR( CV_StsUnsupportedFormat,
            "Floating-point coordinates are not supported here" );

    if( CV_IS_SEQ( hull ))
    {
        int hulltype = CV_SEQ_ELTYPE( hull );
        if( hulltype != CV_SEQ_ELTYPE_PPOINT && hulltype != CV_SEQ_ELTYPE_INDEX )
            CV_ERROR( CV_StsUnsupportedFormat,
                "Convex hull must represented as a sequence "
                "of indices or sequence of pointers" );
        if( !storage )
            storage = hull->storage;
    }
    else
    {
        CvMat* mat = (CvMat*)hull;

        if( !CV_IS_MAT( hull ))
            CV_ERROR(CV_StsBadArg, "Convex hull is neither sequence nor matrix");

        if( mat->cols != 1 && mat->rows != 1 ||
            !CV_IS_MAT_CONT(mat->type) || CV_MAT_TYPE(mat->type) != CV_32SC1 )
            CV_ERROR( CV_StsBadArg,
            "The matrix should be 1-dimensional and continuous array of int's" );

        if( mat->cols + mat->rows - 1 > ptseq->total )
            CV_ERROR( CV_StsBadSize, "Convex hull is larger than the point sequence" );

        CV_CALL( hull = cvMakeSeqHeaderForArray(
            CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED,
            sizeof(CvContour), CV_ELEM_SIZE(mat->type), mat->data.ptr,
            mat->cols + mat->rows - 1, &hull_header.s, &hullblock ));
    }

    is_index = CV_SEQ_ELTYPE(hull) == CV_SEQ_ELTYPE_INDEX;

    if( !storage )
        CV_ERROR( CV_StsNullPtr, "NULL storage pointer" );

    CV_CALL( defects = cvCreateSeq( CV_SEQ_KIND_GENERIC, sizeof(CvSeq),
                                    sizeof(CvConvexityDefect), storage ));

    if( ptseq->total < 4 || hull->total < 3)
    {
        //CV_ERROR( CV_StsBadSize,
        //    "point seq size must be >= 4, convex hull size must be >= 3" );
        EXIT;
    }

    /* recognize co-orientation of ptseq and its hull */
    {
        int sign = 0;
        int index1, index2, index3;

        if( !is_index )
        {
            CvPoint* pos = *CV_SEQ_ELEM( hull, CvPoint*, 0 );
            CV_CALL( index1 = cvSeqElemIdx( ptseq, pos ));

            pos = *CV_SEQ_ELEM( hull, CvPoint*, 1 );
            CV_CALL( index2 = cvSeqElemIdx( ptseq, pos ));

            pos = *CV_SEQ_ELEM( hull, CvPoint*, 2 );
            CV_CALL( index3 = cvSeqElemIdx( ptseq, pos ));
        }
        else
        {
Exemple #26
0
static void
icvInitPyramidalAlgorithm( const CvMat* imgA, const CvMat* imgB,
                           CvMat* pyrA, CvMat* pyrB,
                           int level, CvTermCriteria * criteria,
                           int max_iters, int flags,
                           uchar *** imgI, uchar *** imgJ,
                           int **step, CvSize** size,
                           double **scale, cv::AutoBuffer<uchar>* buffer )
{
    const int ALIGN = 8;
    int pyrBytes, bufferBytes = 0, elem_size;
    int level1 = level + 1;

    int i;
    CvSize imgSize, levelSize;

    *imgI = *imgJ = 0;
    *step = 0;
    *scale = 0;
    *size = 0;

    /* check input arguments */
    if( ((flags & CV_LKFLOW_PYR_A_READY) != 0 && !pyrA) ||
        ((flags & CV_LKFLOW_PYR_B_READY) != 0 && !pyrB) )
        CV_Error( CV_StsNullPtr, "Some of the precomputed pyramids are missing" );

    if( level < 0 )
        CV_Error( CV_StsOutOfRange, "The number of pyramid levels is negative" );

    switch( criteria->type )
    {
    case CV_TERMCRIT_ITER:
        criteria->epsilon = 0.f;
        break;
    case CV_TERMCRIT_EPS:
        criteria->max_iter = max_iters;
        break;
    case CV_TERMCRIT_ITER | CV_TERMCRIT_EPS:
        break;
    default:
        assert( 0 );
        CV_Error( CV_StsBadArg, "Invalid termination criteria" );
    }

    /* compare squared values */
    criteria->epsilon *= criteria->epsilon;

    /* set pointers and step for every level */
    pyrBytes = 0;

    imgSize = cvGetSize(imgA);
    elem_size = CV_ELEM_SIZE(imgA->type);
    levelSize = imgSize;

    for( i = 1; i < level1; i++ )
    {
        levelSize.width = (levelSize.width + 1) >> 1;
        levelSize.height = (levelSize.height + 1) >> 1;

        int tstep = cvAlign(levelSize.width,ALIGN) * elem_size;
        pyrBytes += tstep * levelSize.height;
    }

    assert( pyrBytes <= imgSize.width * imgSize.height * elem_size * 4 / 3 );

    /* buffer_size = <size for patches> + <size for pyramids> */
    bufferBytes = (int)((level1 >= 0) * ((pyrA->data.ptr == 0) +
        (pyrB->data.ptr == 0)) * pyrBytes +
        (sizeof(imgI[0][0]) * 2 + sizeof(step[0][0]) +
         sizeof(size[0][0]) + sizeof(scale[0][0])) * level1);

    buffer->allocate( bufferBytes );

    *imgI = (uchar **) (uchar*)(*buffer);
    *imgJ = *imgI + level1;
    *step = (int *) (*imgJ + level1);
    *scale = (double *) (*step + level1);
    *size = (CvSize *)(*scale + level1);

    imgI[0][0] = imgA->data.ptr;
    imgJ[0][0] = imgB->data.ptr;
    step[0][0] = imgA->step;
    scale[0][0] = 1;
    size[0][0] = imgSize;

    if( level > 0 )
    {
        uchar *bufPtr = (uchar *) (*size + level1);
        uchar *ptrA = pyrA->data.ptr;
        uchar *ptrB = pyrB->data.ptr;

        if( !ptrA )
        {
            ptrA = bufPtr;
            bufPtr += pyrBytes;
        }

        if( !ptrB )
            ptrB = bufPtr;

        levelSize = imgSize;

        /* build pyramids for both frames */
        for( i = 1; i <= level; i++ )
        {
            int levelBytes;
            CvMat prev_level, next_level;

            levelSize.width = (levelSize.width + 1) >> 1;
            levelSize.height = (levelSize.height + 1) >> 1;

            size[0][i] = levelSize;
            step[0][i] = cvAlign( levelSize.width, ALIGN ) * elem_size;
            scale[0][i] = scale[0][i - 1] * 0.5;

            levelBytes = step[0][i] * levelSize.height;
            imgI[0][i] = (uchar *) ptrA;
            ptrA += levelBytes;

            if( !(flags & CV_LKFLOW_PYR_A_READY) )
            {
                prev_level = cvMat( size[0][i-1].height, size[0][i-1].width, CV_8UC1 );
                next_level = cvMat( size[0][i].height, size[0][i].width, CV_8UC1 );
                cvSetData( &prev_level, imgI[0][i-1], step[0][i-1] );
                cvSetData( &next_level, imgI[0][i], step[0][i] );
                cvPyrDown( &prev_level, &next_level );
            }

            imgJ[0][i] = (uchar *) ptrB;
            ptrB += levelBytes;

            if( !(flags & CV_LKFLOW_PYR_B_READY) )
            {
                prev_level = cvMat( size[0][i-1].height, size[0][i-1].width, CV_8UC1 );
                next_level = cvMat( size[0][i].height, size[0][i].width, CV_8UC1 );
                cvSetData( &prev_level, imgJ[0][i-1], step[0][i-1] );
                cvSetData( &next_level, imgJ[0][i], step[0][i] );
                cvPyrDown( &prev_level, &next_level );
            }
        }
    }
CV_IMPL void
cvSVBkSb( const CvArr* warr, const CvArr* uarr,
          const CvArr* varr, const CvArr* barr,
          CvArr* xarr, int flags )
{
    uchar* buffer = 0;
    int local_alloc = 0;

    CV_FUNCNAME( "cvSVBkSb" );

    __BEGIN__;

    CvMat wstub, *w = (CvMat*)warr;
    CvMat bstub, *b = (CvMat*)barr;
    CvMat xstub, *x = (CvMat*)xarr;
    CvMat ustub, ustub2, *u = (CvMat*)uarr;
    CvMat vstub, vstub2, *v = (CvMat*)varr;
    uchar* tw = 0;
    int type;
    int temp_u = 0, temp_v = 0;
    int u_buf_offset = 0, v_buf_offset = 0, w_buf_offset = 0, t_buf_offset = 0;
    int buf_size = 0, pix_size;
    int m, n, nm;
    int u_rows, u_cols;
    int v_rows, v_cols;

    if( !CV_IS_MAT( w ))
        CV_CALL( w = cvGetMat( w, &wstub ));

    if( !CV_IS_MAT( u ))
        CV_CALL( u = cvGetMat( u, &ustub ));

    if( !CV_IS_MAT( v ))
        CV_CALL( v = cvGetMat( v, &vstub ));

    if( !CV_IS_MAT( x ))
        CV_CALL( x = cvGetMat( x, &xstub ));

    if( !CV_ARE_TYPES_EQ( w, u ) || !CV_ARE_TYPES_EQ( w, v ) || !CV_ARE_TYPES_EQ( w, x ))
        CV_ERROR( CV_StsUnmatchedFormats, "All matrices must have the same type" );

    type = CV_MAT_TYPE( w->type );
    pix_size = CV_ELEM_SIZE(type);

    if( !(flags & CV_SVD_U_T) )
    {
        temp_u = 1;
        u_buf_offset = buf_size;
        buf_size += u->cols*u->rows*pix_size;
        u_rows = u->rows;
        u_cols = u->cols;
    }
    else
    {
        u_rows = u->cols;
        u_cols = u->rows;
    }

    if( !(flags & CV_SVD_V_T) )
    {
        temp_v = 1;
        v_buf_offset = buf_size;
        buf_size += v->cols*v->rows*pix_size;
        v_rows = v->rows;
        v_cols = v->cols;
    }
    else
    {
        v_rows = v->cols;
        v_cols = v->rows;
    }

    m = u_rows;
    n = v_rows;
    nm = MIN(n,m);

    if( (u_rows != u_cols && v_rows != v_cols) || x->rows != v_rows )
        CV_ERROR( CV_StsBadSize, "V or U matrix must be square" );

    if( (w->rows == 1 || w->cols == 1) && w->rows + w->cols - 1 == nm )
    {
        if( CV_IS_MAT_CONT(w->type) )
            tw = w->data.ptr;
        else
        {
            w_buf_offset = buf_size;
            buf_size += nm*pix_size;
        }
    }
    else
    {
        if( w->cols != v_cols || w->rows != u_cols )
            CV_ERROR( CV_StsBadSize, "W must be 1d array of MIN(m,n) elements or "
                                    "matrix which size matches to U and V" );
        w_buf_offset = buf_size;
        buf_size += nm*pix_size;
    }

    if( b )
    {
        if( !CV_IS_MAT( b ))
            CV_CALL( b = cvGetMat( b, &bstub ));
        if( !CV_ARE_TYPES_EQ( w, b ))
            CV_ERROR( CV_StsUnmatchedFormats, "All matrices must have the same type" );
        if( b->cols != x->cols || b->rows != m )
            CV_ERROR( CV_StsUnmatchedSizes, "b matrix must have (m x x->cols) size" );
    }
    else
    {
        b = &bstub;
        memset( b, 0, sizeof(*b));
    }

    t_buf_offset = buf_size;
    buf_size += (MAX(m,n) + b->cols)*pix_size;

    if( buf_size <= CV_MAX_LOCAL_SIZE )
    {
        buffer = (uchar*)cvStackAlloc( buf_size );
        local_alloc = 1;
    }
    else
        CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));

    if( temp_u )
    {
        cvInitMatHeader( &ustub2, u_cols, u_rows, type, buffer + u_buf_offset );
        cvT( u, &ustub2 );
        u = &ustub2;
    }

    if( temp_v )
    {
        cvInitMatHeader( &vstub2, v_cols, v_rows, type, buffer + v_buf_offset );
        cvT( v, &vstub2 );
        v = &vstub2;
    }

    if( !tw )
    {
        int i, shift = w->cols > 1 ? pix_size : 0;
        tw = buffer + w_buf_offset;
        for( i = 0; i < nm; i++ )
            memcpy( tw + i*pix_size, w->data.ptr + i*(w->step + shift), pix_size );
    }

    if( type == CV_32FC1 )
    {
        icvSVBkSb_32f( m, n, (float*)tw, u->data.fl, u->step/sizeof(float),
                       v->data.fl, v->step/sizeof(float),
                       b->data.fl, b->step/sizeof(float), b->cols,
                       x->data.fl, x->step/sizeof(float),
                       (float*)(buffer + t_buf_offset) );
    }
    else if( type == CV_64FC1 )
    {
        icvSVBkSb_64f( m, n, (double*)tw, u->data.db, u->step/sizeof(double),
                       v->data.db, v->step/sizeof(double),
                       b->data.db, b->step/sizeof(double), b->cols,
                       x->data.db, x->step/sizeof(double),
                       (double*)(buffer + t_buf_offset) );
    }
    else
    {
        CV_ERROR( CV_StsUnsupportedFormat, "" );
    }

    __END__;

    if( buffer && !local_alloc )
        cvFree( &buffer );
}
Exemple #28
0
void icvConvertPointsHomogenious( const CvMat* src, CvMat* dst )
{
  CvMat* temp = 0;
  CvMat* denom = 0;

  CV_FUNCNAME( "cvConvertPointsHomogenious" );

  __BEGIN__;

  int i, s_count, s_dims, d_count, d_dims;
  CvMat _src, _dst, _ones;
  CvMat* ones = 0;

  if( !CV_IS_MAT(src) )
    CV_ERROR( !src ? CV_StsNullPtr : CV_StsBadArg,
              "The input parameter is not a valid matrix" );

  if( !CV_IS_MAT(dst) )
    CV_ERROR( !dst ? CV_StsNullPtr : CV_StsBadArg,
              "The output parameter is not a valid matrix" );

  if( src == dst || src->data.ptr == dst->data.ptr )
  {
    if( src != dst && (!CV_ARE_TYPES_EQ(src, dst) ||
                       !CV_ARE_SIZES_EQ(src,dst)) )
      CV_ERROR( CV_StsBadArg, "Invalid inplace operation" );
    EXIT;
  }

  if( src->rows > src->cols )
  {
    if( !((src->cols > 1) ^ (CV_MAT_CN(src->type) > 1)) )
      CV_ERROR( CV_StsBadSize,
                "Either the number of channels or columns or "
                "rows must be =1" );

    s_dims = CV_MAT_CN(src->type)*src->cols;
    s_count = src->rows;
  }
  else
  {
    if( !((src->rows > 1) ^ (CV_MAT_CN(src->type) > 1)) )
      CV_ERROR( CV_StsBadSize,
                "Either the number of channels or columns or "
                "rows must be =1" );

    s_dims = CV_MAT_CN(src->type)*src->rows;
    s_count = src->cols;
  }

  if( src->rows == 1 || src->cols == 1 )
    src = cvReshape( src, &_src, 1, s_count );

  if( dst->rows > dst->cols )
  {
    if( !((dst->cols > 1) ^ (CV_MAT_CN(dst->type) > 1)) )
      CV_ERROR( CV_StsBadSize,
                "Either the number of channels or columns or "
                "rows in the input matrix must be =1" );

    d_dims = CV_MAT_CN(dst->type)*dst->cols;
    d_count = dst->rows;
  }
  else
  {
    if( !((dst->rows > 1) ^ (CV_MAT_CN(dst->type) > 1)) )
      CV_ERROR( CV_StsBadSize,
                "Either the number of channels or columns or "
                "rows in the output matrix must be =1" );

    d_dims = CV_MAT_CN(dst->type)*dst->rows;
    d_count = dst->cols;
  }

  if( dst->rows == 1 || dst->cols == 1 )
    dst = cvReshape( dst, &_dst, 1, d_count );

  if( s_count != d_count )
    CV_ERROR( CV_StsUnmatchedSizes, "Both matrices must have the "
                "same number of points" );

  if( CV_MAT_DEPTH(src->type) < CV_32F || CV_MAT_DEPTH(dst->type) < CV_32F )
    CV_ERROR( CV_StsUnsupportedFormat,
              "Both matrices must be floating-point "
                "(single or double precision)" );

  if( s_dims < 2 || s_dims > 4 || d_dims < 2 || d_dims > 4 )
    CV_ERROR( CV_StsOutOfRange,
              "Both input and output point dimensionality "
                "must be 2, 3 or 4" );

  if( s_dims < d_dims - 1 || s_dims > d_dims + 1 )
    CV_ERROR( CV_StsUnmatchedSizes,
              "The dimensionalities of input and output "
                "point sets differ too much" );

  if( s_dims == d_dims - 1 )
  {
    if( d_count == dst->rows )
    {
      ones = cvGetSubRect( dst, &_ones, cvRect( s_dims, 0, 1, d_count ));
      dst = cvGetSubRect( dst, &_dst, cvRect( 0, 0, s_dims, d_count ));
    }
    else
    {
      ones = cvGetSubRect( dst, &_ones, cvRect( 0, s_dims, d_count, 1 ));
      dst = cvGetSubRect( dst, &_dst, cvRect( 0, 0, d_count, s_dims ));
    }
  }

  if( s_dims <= d_dims )
  {
    if( src->rows == dst->rows && src->cols == dst->cols )
    {
      if( CV_ARE_TYPES_EQ( src, dst ) )
        cvCopy( src, dst );
      else
        cvConvert( src, dst );
    }
    else
    {
      if( !CV_ARE_TYPES_EQ( src, dst ))
      {
        CV_CALL( temp = cvCreateMat( src->rows, src->cols, dst->type ));
        cvConvert( src, temp );
        src = temp;
      }
      cvTranspose( src, dst );
    }

    if( ones )
      cvSet( ones, cvRealScalar(1.) );
  }
  else
  {
    int s_plane_stride, s_stride, d_plane_stride, d_stride, elem_size;

    if( !CV_ARE_TYPES_EQ( src, dst ))
    {
      CV_CALL( temp = cvCreateMat( src->rows, src->cols, dst->type ));
      cvConvert( src, temp );
      src = temp;
    }

    elem_size = CV_ELEM_SIZE(src->type);

    if( s_count == src->cols )
      s_plane_stride = src->step / elem_size, s_stride = 1;
    else
      s_stride = src->step / elem_size, s_plane_stride = 1;

    if( d_count == dst->cols )
      d_plane_stride = dst->step / elem_size, d_stride = 1;
    else
      d_stride = dst->step / elem_size, d_plane_stride = 1;

    CV_CALL( denom = cvCreateMat( 1, d_count, dst->type ));

    if( CV_MAT_DEPTH(dst->type) == CV_32F )
    {
      const float* xs = src->data.fl;
      const float* ys = xs + s_plane_stride;
      const float* zs = 0;
      const float* ws = xs + (s_dims - 1)*s_plane_stride;

      float* iw = denom->data.fl;

      float* xd = dst->data.fl;
      float* yd = xd + d_plane_stride;
      float* zd = 0;

      if( d_dims == 3 )
      {
        zs = ys + s_plane_stride;
        zd = yd + d_plane_stride;
      }

      for( i = 0; i < d_count; i++, ws += s_stride )
      {
        float t = *ws;
        iw[i] = t ? t : 1.f;
      }

      cvDiv( 0, denom, denom );

      if( d_dims == 3 )
        for( i = 0; i < d_count; i++ )
        {
          float w = iw[i];
          float x = *xs * w, y = *ys * w, z = *zs * w;
          xs += s_stride; ys += s_stride; zs += s_stride;
          *xd = x; *yd = y; *zd = z;
          xd += d_stride; yd += d_stride; zd += d_stride;
        }
      else
        for( i = 0; i < d_count; i++ )
        {
          float w = iw[i];
          float x = *xs * w, y = *ys * w;
          xs += s_stride; ys += s_stride;
          *xd = x; *yd = y;
          xd += d_stride; yd += d_stride;
        }
    }
    else
    {
      const double* xs = src->data.db;
      const double* ys = xs + s_plane_stride;
      const double* zs = 0;
      const double* ws = xs + (s_dims - 1)*s_plane_stride;

      double* iw = denom->data.db;

      double* xd = dst->data.db;
      double* yd = xd + d_plane_stride;
      double* zd = 0;

      if( d_dims == 3 )
      {
        zs = ys + s_plane_stride;
        zd = yd + d_plane_stride;
      }

      for( i = 0; i < d_count; i++, ws += s_stride )
      {
        double t = *ws;
        iw[i] = t ? t : 1.;
      }

      cvDiv( 0, denom, denom );

      if( d_dims == 3 )
        for( i = 0; i < d_count; i++ )
        {
          double w = iw[i];
          double x = *xs * w, y = *ys * w, z = *zs * w;
          xs += s_stride; ys += s_stride; zs += s_stride;
          *xd = x; *yd = y; *zd = z;
          xd += d_stride; yd += d_stride; zd += d_stride;
        }
      else
        for( i = 0; i < d_count; i++ )
        {
          double w = iw[i];
          double x = *xs * w, y = *ys * w;
          xs += s_stride; ys += s_stride;
          *xd = x; *yd = y;
          xd += d_stride; yd += d_stride;
        }
    }
  }

  __END__;

  cvReleaseMat( &denom );
  cvReleaseMat( &temp );
}
Exemple #29
0
inline
size_t HostMem::elemSize() const
{
    return CV_ELEM_SIZE(flags);
}
CV_IMPL void
cvFitLine( const CvArr* array, int dist, double param,
           double reps, double aeps, float *line )
{
    cv::AutoBuffer<schar> buffer;

    schar* points = 0;
    union { CvContour contour; CvSeq seq; } header;
    CvSeqBlock block;
    CvSeq* ptseq = (CvSeq*)array;
    int type;

    if( !line )
        CV_Error( CV_StsNullPtr, "NULL pointer to line parameters" );

    if( CV_IS_SEQ(ptseq) )
    {
        type = CV_SEQ_ELTYPE(ptseq);
        if( ptseq->total == 0 )
            CV_Error( CV_StsBadSize, "The sequence has no points" );
        if( (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) ||
            CV_ELEM_SIZE(type) != ptseq->elem_size )
            CV_Error( CV_StsUnsupportedFormat,
                "Input sequence must consist of 2d points or 3d points" );
    }
    else
    {
        CvMat* mat = (CvMat*)array;
        type = CV_MAT_TYPE(mat->type);
        if( !CV_IS_MAT(mat))
            CV_Error( CV_StsBadArg, "Input array is not a sequence nor matrix" );

        if( !CV_IS_MAT_CONT(mat->type) ||
            (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) ||
            (mat->width != 1 && mat->height != 1))
            CV_Error( CV_StsBadArg,
            "Input array must be 1d continuous array of 2d or 3d points" );

        ptseq = cvMakeSeqHeaderForArray(
            CV_SEQ_KIND_GENERIC|type, sizeof(CvContour), CV_ELEM_SIZE(type), mat->data.ptr,
            mat->width + mat->height - 1, &header.seq, &block );
    }

    if( reps < 0 || aeps < 0 )
        CV_Error( CV_StsOutOfRange, "Both reps and aeps must be non-negative" );

    if( CV_MAT_DEPTH(type) == CV_32F && ptseq->first->next == ptseq->first )
    {
        /* no need to copy data in this case */
        points = ptseq->first->data;
    }
    else
    {
        buffer.allocate(ptseq->total*CV_ELEM_SIZE(type));
        points = buffer;
        cvCvtSeqToArray( ptseq, points, CV_WHOLE_SEQ );

        if( CV_MAT_DEPTH(type) != CV_32F )
        {
            int i, total = ptseq->total*CV_MAT_CN(type);
            assert( CV_MAT_DEPTH(type) == CV_32S );

            for( i = 0; i < total; i++ )
                ((float*)points)[i] = (float)((int*)points)[i];
        }
    }

    if( dist == CV_DIST_USER )
        CV_Error( CV_StsBadArg, "User-defined distance is not allowed" );

    if( CV_MAT_CN(type) == 2 )
    {
        IPPI_CALL( icvFitLine2D( (CvPoint2D32f*)points, ptseq->total,
                                 dist, (float)param, (float)reps, (float)aeps, line ));
    }
    else
    {
        IPPI_CALL( icvFitLine3D( (CvPoint3D32f*)points, ptseq->total,
                                 dist, (float)param, (float)reps, (float)aeps, line ));
    }
}