bool CvVideoWriter_VFW::writeFrame( const IplImage* image ) { bool result = false; CV_FUNCNAME( "CvVideoWriter_VFW::writeFrame" ); __BEGIN__; if( !image ) EXIT; if( !compressed && !createStreams( cvGetSize(image), image->nChannels > 1 )) EXIT; if( image->width != tempFrame->width || image->height != tempFrame->height ) CV_ERROR( CV_StsUnmatchedSizes, "image size is different from the currently set frame size" ); if( image->nChannels != tempFrame->nChannels || image->depth != tempFrame->depth || image->origin == 0 || image->widthStep != cvAlign(image->width*image->nChannels*((image->depth & 255)/8), 4)) { cvConvertImage( image, tempFrame, image->origin == 0 ? CV_CVTIMG_FLIP : 0 ); image = (const IplImage*)tempFrame; } result = AVIStreamWrite( compressed, pos++, 1, image->imageData, image->imageSize, AVIIF_KEYFRAME, 0, 0 ) == AVIERR_OK; __END__; return result; }
CvMat* icvIPPFilterInit( const CvMat* src, int stripe_size, CvSize ksize ) { CvSize temp_size; int pix_size = CV_ELEM_SIZE(src->type); temp_size.width = cvAlign(src->cols + ksize.width - 1,8/CV_ELEM_SIZE(src->type & CV_MAT_DEPTH_MASK)); //temp_size.width = src->cols + ksize.width - 1; temp_size.height = (stripe_size*2 + temp_size.width*pix_size) / (temp_size.width*pix_size*2); temp_size.height = MAX( temp_size.height, ksize.height ); temp_size.height = MIN( temp_size.height, src->rows + ksize.height - 1 ); return cvCreateMat( temp_size.height, temp_size.width, src->type ); }
void CvBoxFilter::start_process( CvSlice x_range, int width ) { CvBaseImageFilter::start_process( x_range, width ); int i, psz = CV_ELEM_SIZE(work_type); uchar* s; buf_end -= buf_step; buf_max_count--; assert( buf_max_count >= max_ky*2 + 1 ); s = sum = buf_end + cvAlign((width + ksize.width - 1)*CV_ELEM_SIZE(src_type), ALIGN); sum_count = 0; width *= psz; for( i = 0; i < width; i++ ) s[i] = (uchar)0; }
/* Initialize allocated storage: */ static void icvInitMemStorage( CvMemStorage* storage, int block_size ) { if( !storage ) CV_Error( CV_StsNullPtr, "" ); if( block_size <= 0 ) block_size = CV_STORAGE_BLOCK_SIZE; block_size = cvAlign( block_size, CV_STRUCT_ALIGN ); assert( sizeof(CvMemBlock) % CV_STRUCT_ALIGN == 0 ); memset( storage, 0, sizeof( *storage )); storage->signature = CV_STORAGE_MAGIC_VAL; storage->block_size = block_size; }
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 ); }
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 ); } } }
static int icvMinimalPyramidSize( CvSize imgSize ) { return cvAlign(imgSize.width,8) * imgSize.height / 3; }
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; }
CV_IMPL void cvWriteRawData( CvFileStorage* fs, const void* _data, int len, const char* dt ) { if (fs->is_default_using_base64 || fs->state_of_writing_base64 == base64::fs::InUse ) { cvWriteRawDataBase64( fs, _data, len, dt ); return; } else if ( fs->state_of_writing_base64 == base64::fs::Uncertain ) { switch_to_Base64_state( fs, base64::fs::NotUse ); } const char* data0 = (const char*)_data; int offset = 0; int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2], k, fmt_pair_count; char buf[256] = ""; CV_CHECK_OUTPUT_FILE_STORAGE( fs ); if( len < 0 ) CV_Error( CV_StsOutOfRange, "Negative number of elements" ); fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); if( !len ) return; if( !data0 ) CV_Error( CV_StsNullPtr, "Null data pointer" ); if( fmt_pair_count == 1 ) { fmt_pairs[0] *= len; len = 1; } for(;len--;) { for( k = 0; k < fmt_pair_count; k++ ) { int i, count = fmt_pairs[k*2]; int elem_type = fmt_pairs[k*2+1]; int elem_size = CV_ELEM_SIZE(elem_type); const char* data, *ptr; offset = cvAlign( offset, elem_size ); data = data0 + offset; for( i = 0; i < count; i++ ) { switch( elem_type ) { case CV_8U: ptr = icv_itoa( *(uchar*)data, buf, 10 ); data++; break; case CV_8S: ptr = icv_itoa( *(char*)data, buf, 10 ); data++; break; case CV_16U: ptr = icv_itoa( *(ushort*)data, buf, 10 ); data += sizeof(ushort); break; case CV_16S: ptr = icv_itoa( *(short*)data, buf, 10 ); data += sizeof(short); break; case CV_32S: ptr = icv_itoa( *(int*)data, buf, 10 ); data += sizeof(int); break; case CV_32F: ptr = icvFloatToString( buf, *(float*)data ); data += sizeof(float); break; case CV_64F: ptr = icvDoubleToString( buf, *(double*)data ); data += sizeof(double); break; case CV_USRTYPE1: /* reference */ ptr = icv_itoa( (int)*(size_t*)data, buf, 10 ); data += sizeof(size_t); break; default: CV_Error( CV_StsUnsupportedFormat, "Unsupported type" ); return; } if( fs->fmt == CV_STORAGE_FORMAT_XML ) { int buf_len = (int)strlen(ptr); icvXMLWriteScalar( fs, 0, ptr, buf_len ); } else if ( fs->fmt == CV_STORAGE_FORMAT_YAML ) { icvYMLWrite( fs, 0, ptr ); } else { if( elem_type == CV_32F || elem_type == CV_64F ) { size_t buf_len = strlen(ptr); if( buf_len > 0 && ptr[buf_len-1] == '.' ) { // append zero if CV_32F or CV_64F string ends with decimal place to match JSON standard // ptr will point to buf, so can write to buf given ptr is const buf[buf_len] = '0'; buf[buf_len+1] = '\0'; } } icvJSONWrite( fs, 0, ptr ); } } offset = (int)(data - data0); } } }
CV_IMPL void cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, int len, void* _data, const char* dt ) { char* data0 = (char*)_data; int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2], k = 0, fmt_pair_count; int i = 0, count = 0; CV_CHECK_FILE_STORAGE( fs ); if( !reader || !data0 ) CV_Error( CV_StsNullPtr, "Null pointer to reader or destination array" ); if( !reader->seq && len != 1 ) CV_Error( CV_StsBadSize, "The readed sequence is a scalar, thus len must be 1" ); fmt_pair_count = icvDecodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); size_t step = ::icvCalcStructSize(dt, 0); for(;;) { int offset = 0; for( k = 0; k < fmt_pair_count; k++ ) { int elem_type = fmt_pairs[k*2+1]; int elem_size = CV_ELEM_SIZE(elem_type); char* data; count = fmt_pairs[k*2]; offset = cvAlign( offset, elem_size ); data = data0 + offset; for( i = 0; i < count; i++ ) { CvFileNode* node = (CvFileNode*)reader->ptr; if( CV_NODE_IS_INT(node->tag) ) { int ival = node->data.i; switch( elem_type ) { case CV_8U: *(uchar*)data = cv::saturate_cast<uchar>(ival); data++; break; case CV_8S: *(char*)data = cv::saturate_cast<schar>(ival); data++; break; case CV_16U: *(ushort*)data = cv::saturate_cast<ushort>(ival); data += sizeof(ushort); break; case CV_16S: *(short*)data = cv::saturate_cast<short>(ival); data += sizeof(short); break; case CV_32S: *(int*)data = ival; data += sizeof(int); break; case CV_32F: *(float*)data = (float)ival; data += sizeof(float); break; case CV_64F: *(double*)data = (double)ival; data += sizeof(double); break; case CV_USRTYPE1: /* reference */ *(size_t*)data = ival; data += sizeof(size_t); break; default: CV_Error( CV_StsUnsupportedFormat, "Unsupported type" ); return; } } else if( CV_NODE_IS_REAL(node->tag) ) { double fval = node->data.f; int ival; switch( elem_type ) { case CV_8U: ival = cvRound(fval); *(uchar*)data = cv::saturate_cast<uchar>(ival); data++; break; case CV_8S: ival = cvRound(fval); *(char*)data = cv::saturate_cast<schar>(ival); data++; break; case CV_16U: ival = cvRound(fval); *(ushort*)data = cv::saturate_cast<ushort>(ival); data += sizeof(ushort); break; case CV_16S: ival = cvRound(fval); *(short*)data = cv::saturate_cast<short>(ival); data += sizeof(short); break; case CV_32S: ival = cvRound(fval); *(int*)data = ival; data += sizeof(int); break; case CV_32F: *(float*)data = (float)fval; data += sizeof(float); break; case CV_64F: *(double*)data = fval; data += sizeof(double); break; case CV_USRTYPE1: /* reference */ ival = cvRound(fval); *(size_t*)data = ival; data += sizeof(size_t); break; default: CV_Error( CV_StsUnsupportedFormat, "Unsupported type" ); return; } } else CV_Error( CV_StsError, "The sequence element is not a numerical scalar" ); CV_NEXT_SEQ_ELEM( sizeof(CvFileNode), *reader ); if( !--len ) goto end_loop; } offset = (int)(data - data0); } data0 += step; } end_loop: if( i != count - 1 || k != fmt_pair_count - 1 ) CV_Error( CV_StsBadSize, "The sequence slice does not fit an integer number of records" ); if( !reader->seq ) reader->ptr -= sizeof(CvFileNode); }
CV_IMPL void cvCalcOpticalFlowBM( const void* srcarrA, const void* srcarrB, CvSize blockSize, CvSize shiftSize, CvSize maxRange, int usePrevious, void* velarrx, void* velarry ) { CvMat stubA, *srcA = cvGetMat( srcarrA, &stubA ); CvMat stubB, *srcB = cvGetMat( srcarrB, &stubB ); CvMat stubx, *velx = cvGetMat( velarrx, &stubx ); CvMat stuby, *vely = cvGetMat( velarry, &stuby ); if( !CV_ARE_TYPES_EQ( srcA, srcB )) CV_Error( CV_StsUnmatchedFormats, "Source images have different formats" ); if( !CV_ARE_TYPES_EQ( velx, vely )) CV_Error( CV_StsUnmatchedFormats, "Destination images have different formats" ); CvSize velSize = { (srcA->width - blockSize.width)/shiftSize.width, (srcA->height - blockSize.height)/shiftSize.height }; if( !CV_ARE_SIZES_EQ( srcA, srcB ) || !CV_ARE_SIZES_EQ( velx, vely ) || velx->width != velSize.width || vely->height != velSize.height ) CV_Error( CV_StsUnmatchedSizes, "" ); if( CV_MAT_TYPE( srcA->type ) != CV_8UC1 || CV_MAT_TYPE( velx->type ) != CV_32FC1 ) CV_Error( CV_StsUnsupportedFormat, "Source images must have 8uC1 type and " "destination images must have 32fC1 type" ); if( srcA->step != srcB->step || velx->step != vely->step ) CV_Error( CV_BadStep, "two source or two destination images have different steps" ); const int SMALL_DIFF=2; const int BIG_DIFF=128; // scanning scheme coordinates cv::vector<CvPoint> _ss((2 * maxRange.width + 1) * (2 * maxRange.height + 1)); CvPoint* ss = &_ss[0]; int ss_count = 0; int blWidth = blockSize.width, blHeight = blockSize.height; int blSize = blWidth*blHeight; int acceptLevel = blSize * SMALL_DIFF; int escapeLevel = blSize * BIG_DIFF; int i, j; cv::vector<uchar> _blockA(cvAlign(blSize + 16, 16)); uchar* blockA = (uchar*)cvAlignPtr(&_blockA[0], 16); // Calculate scanning scheme int min_count = MIN( maxRange.width, maxRange.height ); // use spiral search pattern // // 9 10 11 12 // 8 1 2 13 // 7 * 3 14 // 6 5 4 15 //... 20 19 18 17 // for( i = 0; i < min_count; i++ ) { // four cycles along sides int x = -i-1, y = x; // upper side for( j = -i; j <= i + 1; j++, ss_count++ ) { ss[ss_count].x = ++x; ss[ss_count].y = y; } // right side for( j = -i; j <= i + 1; j++, ss_count++ ) { ss[ss_count].x = x; ss[ss_count].y = ++y; } // bottom side for( j = -i; j <= i + 1; j++, ss_count++ ) { ss[ss_count].x = --x; ss[ss_count].y = y; } // left side for( j = -i; j <= i + 1; j++, ss_count++ ) { ss[ss_count].x = x; ss[ss_count].y = --y; } } // the rest part if( maxRange.width < maxRange.height ) { int xleft = -min_count; // cycle by neighbor rings for( i = min_count; i < maxRange.height; i++ ) { // two cycles by x int y = -(i + 1); int x = xleft; // upper side for( j = -maxRange.width; j <= maxRange.width; j++, ss_count++, x++ ) { ss[ss_count].x = x; ss[ss_count].y = y; } x = xleft; y = -y; // bottom side for( j = -maxRange.width; j <= maxRange.width; j++, ss_count++, x++ ) { ss[ss_count].x = x; ss[ss_count].y = y; } } } else if( maxRange.width > maxRange.height ) { int yupper = -min_count; // cycle by neighbor rings for( i = min_count; i < maxRange.width; i++ ) { // two cycles by y int x = -(i + 1); int y = yupper; // left side for( j = -maxRange.height; j <= maxRange.height; j++, ss_count++, y++ ) { ss[ss_count].x = x; ss[ss_count].y = y; } y = yupper; x = -x; // right side for( j = -maxRange.height; j <= maxRange.height; j++, ss_count++, y++ ) { ss[ss_count].x = x; ss[ss_count].y = y; } } } int maxX = srcB->cols - blockSize.width, maxY = srcB->rows - blockSize.height; const uchar* Adata = srcA->data.ptr; const uchar* Bdata = srcB->data.ptr; int Astep = srcA->step, Bstep = srcB->step; // compute the flow for( i = 0; i < velx->rows; i++ ) { float* vx = (float*)(velx->data.ptr + velx->step*i); float* vy = (float*)(vely->data.ptr + vely->step*i); for( j = 0; j < velx->cols; j++ ) { int X1 = j*shiftSize.width, Y1 = i*shiftSize.height, X2, Y2; int offX = 0, offY = 0; if( usePrevious ) { offX = cvRound(vx[j]); offY = cvRound(vy[j]); } int k; for( k = 0; k < blHeight; k++ ) memcpy( blockA + k*blWidth, Adata + Astep*(Y1 + k) + X1, blWidth ); X2 = X1 + offX; Y2 = Y1 + offY; int dist = INT_MAX; if( 0 <= X2 && X2 <= maxX && 0 <= Y2 && Y2 <= maxY ) dist = cmpBlocks( blockA, Bdata + Bstep*Y2 + X2, Bstep, blockSize ); int countMin = 1; int sumx = offX, sumy = offY; if( dist > acceptLevel ) { // do brute-force search for( k = 0; k < ss_count; k++ ) { int dx = offX + ss[k].x; int dy = offY + ss[k].y; X2 = X1 + dx; Y2 = Y1 + dy; if( !(0 <= X2 && X2 <= maxX && 0 <= Y2 && Y2 <= maxY) ) continue; int tmpDist = cmpBlocks( blockA, Bdata + Bstep*Y2 + X2, Bstep, blockSize ); if( tmpDist < acceptLevel ) { sumx = dx; sumy = dy; countMin = 1; break; } if( tmpDist < dist ) { dist = tmpDist; sumx = dx; sumy = dy; countMin = 1; } else if( tmpDist == dist ) { sumx += dx; sumy += dy; countMin++; } } if( dist > escapeLevel ) { sumx = offX; sumy = offY; countMin = 1; } } vx[j] = (float)sumx/countMin; vy[j] = (float)sumy/countMin; } } }