//-------------------------------------------------------------------------------- void ofxCvImage::transform( float angle, float centerX, float centerY, float scaleX, float scaleY, float moveX, float moveY ){ if( !bAllocated ){ ofLogError("ofxCvImage") << "transform(): image not allocated"; return; } float sina = sin(angle * DEG_TO_RAD); float cosa = cos(angle * DEG_TO_RAD); CvMat* transmat = cvCreateMat( 2,3, CV_32F ); cvmSet( transmat, 0,0, scaleX*cosa ); cvmSet( transmat, 0,1, scaleY*sina ); cvmSet( transmat, 0,2, -centerX*scaleX*cosa - centerY*scaleY*sina + moveX + centerX ); cvmSet( transmat, 1,0, -1.0*scaleX*sina ); cvmSet( transmat, 1,1, scaleY*cosa ); cvmSet( transmat, 1,2, -centerY*scaleY*cosa + centerX*scaleX*sina + moveY + centerY); cvWarpAffine( cvImage, cvImageTemp, transmat ); swapTemp(); flagImageChanged(); cvReleaseMat( &transmat ); }
//-------------------------------------------------------------------------------- void ofxCvImage::warpPerspective( const ofPoint& A, const ofPoint& B, const ofPoint& C, const ofPoint& D ) { if( !bAllocated ){ ofLog(OF_LOG_ERROR, "in warpPerspective, need to allocate image first"); return; } // compute matrix for perspectival warping (homography) CvPoint2D32f cvsrc[4]; CvPoint2D32f cvdst[4]; CvMat* translate = cvCreateMat( 3,3, CV_32FC1 ); cvSetZero( translate ); cvdst[0].x = 0; cvdst[0].y = 0; cvdst[1].x = width; cvdst[1].y = 0; cvdst[2].x = width; cvdst[2].y = height; cvdst[3].x = 0; cvdst[3].y = height; cvsrc[0].x = A.x; cvsrc[0].y = A.y; cvsrc[1].x = B.x; cvsrc[1].y = B.y; cvsrc[2].x = C.x; cvsrc[2].y = C.y; cvsrc[3].x = D.x; cvsrc[3].y = D.y; cvWarpPerspectiveQMatrix( cvsrc, cvdst, translate ); // calculate homography cvWarpPerspective( cvImage, cvImageTemp, translate ); swapTemp(); flagImageChanged(); cvReleaseMat( &translate ); }
//-------------------------------------------------------------------------------- void ofxCvImage::warpPerspective( const ofPoint& A, const ofPoint& B, const ofPoint& C, const ofPoint& D ) { if( !bAllocated ){ ofLogError("ofxCvImage") << "warpPerspective(): image not allocated"; return; } // compute matrix for perspectival warping (homography) CvPoint2D32f cvsrc[4]; CvPoint2D32f cvdst[4]; CvMat* translate = cvCreateMat( 3,3, CV_32FC1 ); cvSetZero( translate ); cvdst[0].x = 0; cvdst[0].y = 0; cvdst[1].x = width; cvdst[1].y = 0; cvdst[2].x = width; cvdst[2].y = height; cvdst[3].x = 0; cvdst[3].y = height; cvsrc[0].x = A.x; cvsrc[0].y = A.y; cvsrc[1].x = B.x; cvsrc[1].y = B.y; cvsrc[2].x = C.x; cvsrc[2].y = C.y; cvsrc[3].x = D.x; cvsrc[3].y = D.y; cvGetPerspectiveTransform( cvsrc, cvdst, translate ); // calculate homography cvWarpPerspective( cvImage, cvImageTemp, translate ); swapTemp(); flagImageChanged(); cvReleaseMat( &translate ); }
//-------------------------------------------------------------------------------- void ofxCvGrayscaleImage::threshold( int value, bool invert) { //http://lush.sourceforge.net/lush-manual/01a8321b.html if(invert) cvThreshold( cvImage, cvImageTemp, value, 255, CV_THRESH_BINARY_INV ); else cvThreshold( cvImage, cvImageTemp, value, 255, CV_THRESH_BINARY ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvGrayscaleImage::adaptiveThreshold( int blockSize, int offset, bool invert, bool gauss) { if( !bAllocated ){ ofLogError("ofxCvGrayscaleImage") << "adaptiveThreshold(): image not allocated"; return; } if( blockSize < 2 ) { ofLogNotice("ofxCvGrayscaleImage") << "adaptiveThreshold(): block size " << blockSize << " < minimum, setting to 3"; blockSize = 3; } if( blockSize % 2 == 0 ) { ofLogNotice("ofxCvGrayscaleImage") << "adaptiveThreshold(): block size " << blockSize << " not odd, adding 1"; blockSize++; } int threshold_type = CV_THRESH_BINARY; if(invert) threshold_type = CV_THRESH_BINARY_INV; int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C; if(gauss) adaptive_method = CV_ADAPTIVE_THRESH_GAUSSIAN_C; cvAdaptiveThreshold( cvImage, cvImageTemp, 255, adaptive_method, threshold_type, blockSize, offset); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvGrayscaleImage::adaptiveThreshold( int blockSize, int offset, bool invert, bool gauss) { if( !bAllocated ){ ofLog(OF_LOG_ERROR, "in adaptiveThreshold, image is not allocated"); return; } if( blockSize < 2 ) { ofLog(OF_LOG_NOTICE, "in adaptiveThreshold, value < 2, will make it 3"); blockSize = 3; } if( blockSize % 2 == 0 ) { ofLog(OF_LOG_NOTICE, "in adaptiveThreshold, value not odd -> will add 1 to cover your back"); blockSize++; } int threshold_type = CV_THRESH_BINARY; if(invert) threshold_type = CV_THRESH_BINARY_INV; int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C; if(gauss) adaptive_method = CV_ADAPTIVE_THRESH_GAUSSIAN_C; cvAdaptiveThreshold( cvImage, cvImageTemp, 255, adaptive_method, threshold_type, blockSize, offset); swapTemp(); flagImageChanged(); }
/** * A +-------------+ B * / \ * / \ * / \ * D +-------------------- + C */ void ofCvImage::warpPerspective( const ofPoint& A, const ofPoint& B, const ofPoint& C, const ofPoint& D ) { // compute matrix for perspectival warping (homography) CvPoint2D32f cvsrc[4]; CvPoint2D32f cvdst[4]; CvMat* translate = cvCreateMat( 3,3, CV_32FC1 ); cvSetZero( translate ); cvsrc[0].x = 0; cvsrc[0].y = 0; cvsrc[1].x = width; cvsrc[1].y = 0; cvsrc[2].x = width; cvsrc[2].y = height; cvsrc[3].x = 0; cvsrc[3].y = height; cvdst[0].x = A.x; cvdst[0].y = A.y; cvdst[1].x = B.x; cvdst[1].y = B.y; cvdst[2].x = C.x; cvdst[2].y = C.y; cvdst[3].x = D.x; cvdst[3].y = D.y; cvWarpPerspectiveQMatrix( cvsrc, cvdst, translate ); // calculate homography cvWarpPerspective( cvImage, cvImageTemp, translate ); swapTemp(); cvReleaseMat( &translate ); }
//-------------------------------------------------------------------------------- void ofxCvImage::operator *= ( ofxCvImage& mom ) { if( !mom.bAllocated ){ ofLog(OF_LOG_ERROR, "in *=, mom needs to be allocated"); return; } if( !bAllocated ){ ofLog(OF_LOG_NOTICE, "in *=, allocating to match dimensions"); allocate(mom.getWidth(), mom.getHeight()); } if( mom.getCvImage()->nChannels == cvImage->nChannels && mom.getCvImage()->depth == cvImage->depth ) { if( matchingROI(getROI(), mom.getROI()) ) { float scalef = 1.0f / 255.0f; cvMul( cvImage, mom.getCvImage(), cvImageTemp, scalef ); swapTemp(); flagImageChanged(); } else { ofLog(OF_LOG_ERROR, "in *=, ROI mismatch"); } } else { ofLog(OF_LOG_ERROR, "in *=, images need to have matching type"); } }
//-------------------------------------------------------------------------------- void ofxCvImage::operator &= ( ofxCvImage& mom ) { if( !mom.bAllocated ){ ofLogError("ofxCvImage") << "operator&=: source image not allocated"; return; } if( !bAllocated ){ ofLogNotice("ofxCvImage") << "operator&=: allocating to match dimensions: " << mom.getWidth() << " " << mom.getHeight(); allocate(mom.getWidth(), mom.getHeight()); } if( mom.getCvImage()->nChannels == cvImage->nChannels && mom.getCvImage()->depth == cvImage->depth ) { if( matchingROI(getROI(), mom.getROI()) ) { cvAnd( cvImage, mom.getCvImage(), cvImageTemp ); swapTemp(); flagImageChanged(); } else { ofLogError("ofxCvImage") << "operator&=: region of interest mismatch"; } } else { ofLogError("ofxCvImage") << "operator&=: images need to have matching type"; } }
//-------------------------------------------------------------------------------- void ofxCvImage::operator *= ( ofxCvImage& mom ) { if( !mom.bAllocated ){ ofLogError("ofxCvImage") << "operator*=: mom needs to be allocated"; return; } if( !bAllocated ){ ofLogNotice("ofxCvImage") << "operator*=: allocating to match dimensions: " << mom.getWidth() << " " << mom.getHeight(); allocate(mom.getWidth(), mom.getHeight()); } if( mom.getCvImage()->nChannels == cvImage->nChannels && mom.getCvImage()->depth == cvImage->depth ) { if( matchingROI(getROI(), mom.getROI()) ) { float scalef = 1.0f / 255.0f; cvMul( cvImage, mom.getCvImage(), cvImageTemp, scalef ); swapTemp(); flagImageChanged(); } else { ofLogError("ofxCvImage") << "operator*=: region of interest mismatch"; } } else { ofLogError("ofxCvImage") << "operator*=: images type mismatch"; } }
//-------------------------------------------------------------------------------- void ofxCvFloatImage::operator *= ( ofxCvFloatImage& mom ) { if( mom.width == width && mom.height == height ) { cvMul( cvImage, mom.getCvImage(), cvImageTemp ); swapTemp(); } else { cout << "error in *=, images are different sizes" << endl; } }
//-------------------------------------------------------------------------------- void ofxCvColorImage::operator += ( ofxCvColorImage& mom ) { if( mom.width == width && mom.height == height ) { cvAdd( cvImage, mom.getCvImage(), cvImageTemp ); swapTemp(); } else { cout << "error in +=, images are different sizes" << endl; } }
//-------------------------------------------------------------------------------- void CPUImageFilter::amplify ( CPUImageFilter& mom, float level ) { float scalef = level / 128.0f; cvMul( mom.getCvImage(), mom.getCvImage(), cvImageTemp, scalef ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvColorImage::convertHsvToRgb(){ if( !bAllocated ){ ofLogError("ofxCvColorImage") << "convertHsvToRgb(): image not allocated"; return; } cvCvtColor( cvImage, cvImageTemp, CV_HSV2RGB); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvImage::erode() { if( !bAllocated ){ ofLogError("ofxCvImage") << "erode(): image not allocated"; return; } cvErode( cvImage, cvImageTemp, 0, 1 ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvImage::operator += ( float value ) { if( !bAllocated ){ ofLog(OF_LOG_ERROR, "in -=, need to allocate image first"); return; } cvAddS( cvImage, cvScalar(value), cvImageTemp ); swapTemp(); flagImageChanged(); }
// Image Filter Operations //-------------------------------------------------------------------------------- void ofxCvImage::dilate(int iterations) { if( !bAllocated ){ ofLogError("ofxCvImage") << "dilate(): image not allocated"; return; } cvDilate( cvImage, cvImageTemp, 0, iterations ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvColorImage::operator -= ( float value ) { if( !bAllocated ){ ofLogError("ofxCvColorImage") << "set(): image not allocated"; return; } cvSubS( cvImage, cvScalar(value, value, value), cvImageTemp ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvImage::remap( IplImage* mapX, IplImage* mapY ) { if( !bAllocated ){ ofLog(OF_LOG_ERROR, "in remap, need to allocate image first"); return; } cvRemap( cvImage, cvImageTemp, mapX, mapY ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvImage::erode() { if( !bAllocated ){ ofLog(OF_LOG_ERROR, "in erode, need to allocate image first"); return; } cvErode( cvImage, cvImageTemp, 0, 1 ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvGrayscaleImage::absDiff( ofxCvGrayscaleImage& mom ) { if( matchingROI(getROI(), mom.getROI()) ) { cvAbsDiff( cvImage, mom.getCvImage(), cvImageTemp ); swapTemp(); flagImageChanged(); } else { ofLog(OF_LOG_ERROR, "in *=, ROI mismatch"); } }
//-------------------------------------------------------------------------------- void ofxCvColorImage::operator *= ( ofxCvColorImage& mom ) { float scalef = 1.0f / 255.0f; if( mom.width == width && mom.height == height ) { cvMul( cvImage, mom.getCvImage(), cvImageTemp, scalef ); swapTemp(); } else { cout << "error in *=, images are different sizes" << endl; } }
//-------------------------------------------------------------------------------- void setfilter::amplify ( setfilter& mom, float level ) { //-- amplify weak areas --// float scalef = level / 104.0; //128.0f cvMul( mom.getCvImage(), mom.getCvImage(), cvImageTemp, scalef ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvImage::operator += ( float value ) { if( !bAllocated ){ ofLogError("ofxCvImage") << "operator-=: image not allocated"; return; } cvAddS( cvImage, cvScalar(value), cvImageTemp ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvImage::remap( IplImage* mapX, IplImage* mapY ) { if( !bAllocated ){ ofLogError("ofxCvImage") << "remap(): image not allocated"; return; } cvRemap( cvImage, cvImageTemp, mapX, mapY ); swapTemp(); flagImageChanged(); }
//-------------------------------------------------------------------------------- void ofxCvImage::blurGaussian( int value ) { if( value % 2 == 0 ) { ofLog(OF_LOG_NOTICE, "in blurGaussian, value not odd -> will add 1 to cover your back"); value++; } cvSmooth( cvImage, cvImageTemp, CV_GAUSSIAN ,value ); swapTemp(); flagImageChanged(); }
void ofCvImage::undistort( float radialDistX, float radialDistY, float tangentDistX, float tangentDistY, float focalX, float focalY, float centerX, float centerY ) { float camIntrinsics[] = { focalX, 0, centerX, 0, focalY, centerY, 0, 0, 1 }; float distortionCoeffs[] = { radialDistX, radialDistY, tangentDistX, tangentDistY }; cvUnDistortOnce( cvImage, cvImageTemp, camIntrinsics, distortionCoeffs, 1 ); swapTemp(); }
// Image Transformation Operations // // void ofCvImage::mirror( bool bFlipVertically, bool bFlipHorizontally ) { int flipMode = 0; if( bFlipVertically && !bFlipHorizontally ) flipMode = 0; else if( !bFlipVertically && bFlipHorizontally ) flipMode = 1; else if( bFlipVertically && bFlipHorizontally ) flipMode = -1; else return; cvFlip( cvImage, cvImageTemp, flipMode ); swapTemp(); }
//-------------------------------------------------------------------------------- void ofxCvFloatImage::addWeighted( ofxCvGrayscaleImage& mom, float f ) { if( mom.width == width && mom.height == height ) { IplImage* cvTemp = cvCreateImage( cvSize(width,height), IPL_DEPTH_32F, 1 ); cvConvertScale( mom.getCvImage(), cvTemp, 1, 0 ); //cvConvert( mom.getCvImage(), cvImage ); cvAddWeighted( cvTemp, f, cvImage, 1.0f-f,0, cvImageTemp ); swapTemp(); cvReleaseImage( &cvTemp ); } else { cout << "error in addWeighted, images are different sizes" << endl; } }
//-------------------------------------------------------------------------------- void ofxCvImage::blurGaussian( int value ) { if( !bAllocated ){ ofLogError("ofxCvImage") << "blurGaussian(): image not allocated"; return; } if( value % 2 == 0 ) { ofLogNotice("ofxCvImage") << "blurGaussian(): value " << value << " not odd, adding 1"; value++; } cvSmooth( cvImage, cvImageTemp, CV_GAUSSIAN ,value ); swapTemp(); flagImageChanged(); }