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; }
// 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; }
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; }
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; }
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; } }
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; }
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__; }
// 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
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, ""); }
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 ); }
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 ); }
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; }
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 ); } } } } }
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 ); } } } }
static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
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 ); }
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; }
/* 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 {
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 ); }
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 ); }
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 )); } }