void cvbFastArctan( const float* y, const float* x, float* angle, int len ) { CvMat mx = cvMat( 1, len, CV_32F, (void*)x ); CvMat my = mx; CvMat ma = mx; my.data.fl = (float*)y; ma.data.fl = (float*)angle; cvCartToPolar( &mx, &my, NULL, &ma, 1 ); }
void cvbCartToPolar( const float* y, const float* x, float* magnitude, float* angle, int len ) { CvMat mx = cvMat( 1, len, CV_32F, (void*)x ); CvMat my = mx; CvMat mm = mx; CvMat ma = mx; my.data.fl = (float*)y; mm.data.fl = (float*)magnitude; ma.data.fl = (float*)angle; cvCartToPolar( &mx, &my, &mm, angle ? &ma : NULL, 1 ); }
CV_IMPL void cvCalcMotionGradient( const CvArr* mhiimg, CvArr* maskimg, CvArr* orientation, double delta1, double delta2, int aperture_size ) { cv::Ptr<CvMat> dX_min, dY_max; CvMat mhistub, *mhi = cvGetMat(mhiimg, &mhistub); CvMat maskstub, *mask = cvGetMat(maskimg, &maskstub); CvMat orientstub, *orient = cvGetMat(orientation, &orientstub); CvMat dX_min_row, dY_max_row, orient_row, mask_row; CvSize size; int x, y; float gradient_epsilon = 1e-4f * aperture_size * aperture_size; float min_delta, max_delta; if( !CV_IS_MASK_ARR( mask )) CV_Error( CV_StsBadMask, "" ); if( aperture_size < 3 || aperture_size > 7 || (aperture_size & 1) == 0 ) CV_Error( CV_StsOutOfRange, "aperture_size must be 3, 5 or 7" ); if( delta1 <= 0 || delta2 <= 0 ) CV_Error( CV_StsOutOfRange, "both delta's must be positive" ); if( CV_MAT_TYPE( mhi->type ) != CV_32FC1 || CV_MAT_TYPE( orient->type ) != CV_32FC1 ) CV_Error( CV_StsUnsupportedFormat, "MHI and orientation must be single-channel floating-point images" ); if( !CV_ARE_SIZES_EQ( mhi, mask ) || !CV_ARE_SIZES_EQ( orient, mhi )) CV_Error( CV_StsUnmatchedSizes, "" ); if( orient->data.ptr == mhi->data.ptr ) CV_Error( CV_StsInplaceNotSupported, "orientation image must be different from MHI" ); if( delta1 > delta2 ) { double t; CV_SWAP( delta1, delta2, t ); } size = cvGetMatSize( mhi ); min_delta = (float)delta1; max_delta = (float)delta2; dX_min = cvCreateMat( mhi->rows, mhi->cols, CV_32F ); dY_max = cvCreateMat( mhi->rows, mhi->cols, CV_32F ); // calc Dx and Dy cvSobel( mhi, dX_min, 1, 0, aperture_size ); cvSobel( mhi, dY_max, 0, 1, aperture_size ); cvGetRow( dX_min, &dX_min_row, 0 ); cvGetRow( dY_max, &dY_max_row, 0 ); cvGetRow( orient, &orient_row, 0 ); cvGetRow( mask, &mask_row, 0 ); // calc gradient for( y = 0; y < size.height; y++ ) { dX_min_row.data.ptr = dX_min->data.ptr + y*dX_min->step; dY_max_row.data.ptr = dY_max->data.ptr + y*dY_max->step; orient_row.data.ptr = orient->data.ptr + y*orient->step; mask_row.data.ptr = mask->data.ptr + y*mask->step; cvCartToPolar( &dX_min_row, &dY_max_row, 0, &orient_row, 1 ); // make orientation zero where the gradient is very small for( x = 0; x < size.width; x++ ) { float dY = dY_max_row.data.fl[x]; float dX = dX_min_row.data.fl[x]; if( fabs(dX) < gradient_epsilon && fabs(dY) < gradient_epsilon ) { mask_row.data.ptr[x] = 0; orient_row.data.i[x] = 0; } else mask_row.data.ptr[x] = 1; } } cvErode( mhi, dX_min, 0, (aperture_size-1)/2); cvDilate( mhi, dY_max, 0, (aperture_size-1)/2); // mask off pixels which have little motion difference in their neighborhood for( y = 0; y < size.height; y++ ) { dX_min_row.data.ptr = dX_min->data.ptr + y*dX_min->step; dY_max_row.data.ptr = dY_max->data.ptr + y*dY_max->step; mask_row.data.ptr = mask->data.ptr + y*mask->step; orient_row.data.ptr = orient->data.ptr + y*orient->step; for( x = 0; x < size.width; x++ ) { float d0 = dY_max_row.data.fl[x] - dX_min_row.data.fl[x]; if( mask_row.data.ptr[x] == 0 || d0 < min_delta || max_delta < d0 ) { mask_row.data.ptr[x] = 0; orient_row.data.i[x] = 0; } } } }
IplImage* ComputeSaliency(IplImage* image, int thresh, int scale) { //given a one channel image unsigned int size = floor(pow(2,scale)); //the size to do teh saliency @ IplImage* bw_im = cvCreateImage(cvSize(size,size), IPL_DEPTH_8U,1); cvResize(image, bw_im); IplImage* realInput = cvCreateImage( cvGetSize(bw_im), IPL_DEPTH_32F, 1); IplImage* imaginaryInput = cvCreateImage( cvGetSize(bw_im), IPL_DEPTH_32F, 1); IplImage* complexInput = cvCreateImage( cvGetSize(bw_im), IPL_DEPTH_32F, 2); cvScale(bw_im, realInput, 1.0/255.0); cvZero(imaginaryInput); cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput); CvMat* dft_A = cvCreateMat( size, size, CV_32FC2 ); // copy A to dft_A and pad dft_A with zeros CvMat tmp; cvGetSubRect( dft_A, &tmp, cvRect(0,0, size,size)); cvCopy( complexInput, &tmp ); // cvZero(&tmp); cvDFT( dft_A, dft_A, CV_DXT_FORWARD, size ); cvSplit( dft_A, realInput, imaginaryInput, NULL, NULL ); // Compute the phase angle IplImage* image_Mag = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); IplImage* image_Phase = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); //compute the phase of the spectrum cvCartToPolar(realInput, imaginaryInput, image_Mag, image_Phase, 0); IplImage* log_mag = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); cvLog(image_Mag, log_mag); //Box filter the magnitude, then take the difference IplImage* log_mag_Filt = cvCreateImage(cvSize(size, size), IPL_DEPTH_32F, 1); CvMat* filt = cvCreateMat(3,3, CV_32FC1); cvSet(filt,cvScalarAll(1.0/9.0)); cvFilter2D(log_mag, log_mag_Filt, filt); cvReleaseMat(&filt); cvSub(log_mag, log_mag_Filt, log_mag); cvExp(log_mag, image_Mag); cvPolarToCart(image_Mag, image_Phase, realInput, imaginaryInput,0); cvExp(log_mag, image_Mag); cvMerge(realInput, imaginaryInput, NULL, NULL, dft_A); cvDFT( dft_A, dft_A, CV_DXT_INV_SCALE, size); cvAbs(dft_A, dft_A); cvMul(dft_A,dft_A, dft_A); cvGetSubRect( dft_A, &tmp, cvRect(0,0, size,size)); cvCopy( &tmp, complexInput); cvSplit(complexInput, realInput, imaginaryInput, NULL,NULL); IplImage* result_image = cvCreateImage(cvGetSize(image),IPL_DEPTH_32F, 1); double minv, maxv; CvPoint minl, maxl; cvSmooth(realInput,realInput); cvSmooth(realInput,realInput); cvMinMaxLoc(realInput,&minv,&maxv,&minl,&maxl); printf("Max value %lf, min %lf\n", maxv,minv); cvScale(realInput, realInput, 1.0/(maxv-minv), 1.0*(-minv)/(maxv-minv)); cvResize(realInput, result_image); double threshold = thresh/100.0*cvAvg(realInput).val[0]; cvThreshold(result_image, result_image, threshold, 1.0, CV_THRESH_BINARY); IplImage* final_result = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U, 1); cvScale(result_image, final_result, 255.0, 0.0); cvReleaseImage(&result_image); //cvReleaseImage(&realInput); cvReleaseImage(&imaginaryInput); cvReleaseImage(&complexInput); cvReleaseMat(&dft_A); cvReleaseImage(&bw_im); cvReleaseImage(&image_Mag); cvReleaseImage(&image_Phase); cvReleaseImage(&log_mag); cvReleaseImage(&log_mag_Filt); cvReleaseImage(&bw_im); return final_result; //return bw_im; }
CV_IMPL void cvCalcMotionGradient( const CvArr* mhiimg, CvArr* maskimg, CvArr* orientation, double delta1, double delta2, int aperture_size ) { CvMat *dX_min = 0, *dY_max = 0; IplConvKernel* el = 0; CV_FUNCNAME( "cvCalcMotionGradient" ); __BEGIN__; CvMat mhistub, *mhi = (CvMat*)mhiimg; CvMat maskstub, *mask = (CvMat*)maskimg; CvMat orientstub, *orient = (CvMat*)orientation; CvMat dX_min_row, dY_max_row, orient_row, mask_row; CvSize size; int x, y; float gradient_epsilon = 1e-4f * aperture_size * aperture_size; float min_delta, max_delta; CV_CALL( mhi = cvGetMat( mhi, &mhistub )); CV_CALL( mask = cvGetMat( mask, &maskstub )); CV_CALL( orient = cvGetMat( orient, &orientstub )); if( !CV_IS_MASK_ARR( mask )) CV_ERROR( CV_StsBadMask, "" ); if( aperture_size < 3 || aperture_size > 7 || (aperture_size & 1) == 0 ) CV_ERROR( CV_StsOutOfRange, "aperture_size must be 3, 5 or 7" ); if( delta1 <= 0 || delta2 <= 0 ) CV_ERROR( CV_StsOutOfRange, "both delta's must be positive" ); if( CV_MAT_TYPE( mhi->type ) != CV_32FC1 || CV_MAT_TYPE( orient->type ) != CV_32FC1 ) CV_ERROR( CV_StsUnsupportedFormat, "MHI and orientation must be single-channel floating-point images" ); if( !CV_ARE_SIZES_EQ( mhi, mask ) || !CV_ARE_SIZES_EQ( orient, mhi )) CV_ERROR( CV_StsUnmatchedSizes, "" ); if( orient->data.ptr == mhi->data.ptr ) CV_ERROR( CV_StsInplaceNotSupported, "orientation image must be different from MHI" ); if( delta1 > delta2 ) { double t; CV_SWAP( delta1, delta2, t ); } size = cvGetMatSize( mhi ); min_delta = (float)delta1; max_delta = (float)delta2; CV_CALL( dX_min = cvCreateMat( mhi->rows, mhi->cols, CV_32F )); CV_CALL( dY_max = cvCreateMat( mhi->rows, mhi->cols, CV_32F )); /* calc Dx and Dy */ CV_CALL( cvSobel( mhi, dX_min, 1, 0, aperture_size )); CV_CALL( cvSobel( mhi, dY_max, 0, 1, aperture_size )); cvGetRow( dX_min, &dX_min_row, 0 ); cvGetRow( dY_max, &dY_max_row, 0 ); cvGetRow( orient, &orient_row, 0 ); cvGetRow( mask, &mask_row, 0 ); /* calc gradient */ for( y = 0; y < size.height; y++ ) { dX_min_row.data.ptr = dX_min->data.ptr + y*dX_min->step; dY_max_row.data.ptr = dY_max->data.ptr + y*dY_max->step; orient_row.data.ptr = orient->data.ptr + y*orient->step; mask_row.data.ptr = mask->data.ptr + y*mask->step; cvCartToPolar( &dX_min_row, &dY_max_row, 0, &orient_row, 1 ); /* make orientation zero where the gradient is very small */ for( x = 0; x < size.width; x++ ) { float dY = dY_max_row.data.fl[x]; float dX = dX_min_row.data.fl[x]; if( fabs(dX) < gradient_epsilon && fabs(dY) < gradient_epsilon ) { mask_row.data.ptr[x] = 0; orient_row.data.i[x] = 0; } else mask_row.data.ptr[x] = 1; } } CV_CALL( el = cvCreateStructuringElementEx( aperture_size, aperture_size, aperture_size/2, aperture_size/2, CV_SHAPE_RECT )); cvErode( mhi, dX_min, el ); cvDilate( mhi, dY_max, el ); /* mask off pixels which have little motion difference in their neighborhood */ for( y = 0; y < size.height; y++ ) { dX_min_row.data.ptr = dX_min->data.ptr + y*dX_min->step; dY_max_row.data.ptr = dY_max->data.ptr + y*dY_max->step; mask_row.data.ptr = mask->data.ptr + y*mask->step; orient_row.data.ptr = orient->data.ptr + y*orient->step; for( x = 0; x < size.width; x++ ) { float d0 = dY_max_row.data.fl[x] - dX_min_row.data.fl[x]; if( mask_row.data.ptr[x] == 0 || d0 < min_delta || max_delta < d0 ) { mask_row.data.ptr[x] = 0; orient_row.data.i[x] = 0; } } } __END__; cvReleaseMat( &dX_min ); cvReleaseMat( &dY_max ); cvReleaseStructuringElement( &el ); }