#include "ofCvGrayscaleImage.h" #include "ofCvColorImage.h" #include "ofCvFloatImage.h" //------------------------------------------------------------------------------------ ofCvGrayscaleImage::ofCvGrayscaleImage(){ width = height = 0;; } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::allocate(int _w, int _h){ cvImage = cvCreateImage(cvSize(_w,_h), IPL_DEPTH_8U,1); cvImageTemp = cvCreateImage(cvSize(_w,_h), IPL_DEPTH_8U,1); pixels = new unsigned char[_w*_h]; width = _w; height = _h; tex.allocate(width, height, GL_LUMINANCE); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::clear(){ cvReleaseImage(&cvImage); cvReleaseImage(&cvImageTemp); delete pixels; tex.clear(); width = height = 0;; } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::set(int value){ cvSet(cvImage, cvScalar(value)); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::setFromColorImage(ofCvColorImage mom){ cvCvtColor( mom.getCvImage() ,cvImage, CV_RGB2GRAY); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::setFromPixels(unsigned char * _pixels, int w, int h){ cvSetImageData(cvImage, _pixels, w); for (int i = 0; i < h; i++){ memcpy(pixels + (i * w), cvImage->imageData + (i * cvImage->widthStep), w); } } //------------------------------------------------------------------------------------- unsigned char * ofCvGrayscaleImage::getPixels(){ // copy each line of pixels: for (int i = 0; i < height; i++){ memcpy(pixels + (i * width), cvImage->imageData + (i * cvImage->widthStep), width); } return pixels; } void ofCvGrayscaleImage::draw(float x, float y){ // note, this is a bit ineficient, as we have to // copy the data out of the cvImage into the pixel array // and then upload to texture. We should add // to the texture class an override for pixelstorei // that allows stepped-width image upload: tex.loadData(getPixels(), width, height, GL_LUMINANCE); tex.draw(x,y,width, height); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::swapTemp(){ IplImage * temp; temp = cvImage; cvImage = cvImageTemp; cvImageTemp = temp; } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::contrastStretch(){ double minVal, maxVal; cvMinMaxLoc(cvImage, &minVal, &maxVal, NULL, NULL, 0); double scale=1.0f; double shift=0; if ((maxVal-minVal) != 0){ scale=255.0/(maxVal-minVal); shift=-minVal*scale; } cvConvertScale(cvImage, cvImageTemp, scale, shift); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::threshold(int value){ //http://lush.sourceforge.net/lush-manual/01a8321b.html cvThreshold(cvImage,cvImageTemp,value,255,CV_THRESH_BINARY); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::dilate_3x3(){ cvDilate( cvImage, cvImageTemp, 0, 1 ); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::erode_3x3(){ cvErode( cvImage, cvImageTemp, 0, 1 ); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::blur(){ cvSmooth(cvImage, cvImageTemp, CV_GAUSSIAN , 3); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::blurHeavily(){ cvSmooth(cvImage, cvImageTemp, CV_GAUSSIAN , 33); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::absDiff(ofCvGrayscaleImage mom, ofCvGrayscaleImage dad){ cvAbsDiff(mom.getCvImage(),dad.getCvImage(),cvImage); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::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 ofCvGrayscaleImage::warpIntoMe(ofCvGrayscaleImage mom, ofPoint2f src[4], ofPoint2f dst[4]){ // compute matrix for perspectival warping (homography) CvPoint2D32f cvsrc[4]; CvPoint2D32f cvdst[4]; CvMat *translate = cvCreateMat(3,3,CV_32FC1); cvSetZero(translate); for (int i = 0; i < 4; i++){ cvsrc[i].x = src[i].x; cvsrc[i].y = src[i].y; cvdst[i].x = dst[i].x; cvdst[i].y = dst[i].y; } cvWarpPerspectiveQMatrix(cvsrc, cvdst, translate); // calculate homography cvWarpPerspective( mom.getCvImage(), cvImage, translate); cvReleaseMat(&translate); } //------------------------------------------------------------------------------------- int ofCvGrayscaleImage::countNonZeroInRegion(int x, int y, int w, int h){ int count = 0; cvSetImageROI(cvImage, cvRect(x,y,w,h)); count = cvCountNonZero(cvImage); cvResetImageROI( cvImage ); return count; } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator = ( ofCvGrayscaleImage & mom ){ if (mom.width == width && mom.height == height){ cvCopy(mom.getCvImage(), cvImage, 0); } else { // what do we do? // cvResize? // cvClone? printf("error in =, images are different sizes\n"); } } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator = ( ofCvFloatImage & mom ){ if (mom.width == width && mom.height == height){ //cvCopy(mom.getCvImage(), cvImage, 0); cvConvertScale( mom.getCvImage(), cvImage, 1, 0 ); } else { // what do we do? // cvResize? // cvClone? printf("error in =, images are different sizes\n"); } } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator -= ( ofCvGrayscaleImage & mom ){ if (mom.width == width && mom.height == height){ cvSub(cvImage, mom.getCvImage(), cvImageTemp); swapTemp(); } else { printf("error in -=, images are different sizes\n"); } } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator += ( ofCvGrayscaleImage & mom ){ if (mom.width == width && mom.height == height){ cvAdd(cvImage, mom.getCvImage(), cvImageTemp); swapTemp(); } else { // what do we do? // cvResize? // cvClone? printf("error in =, images are different sizes\n"); } } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator *= ( ofCvGrayscaleImage & mom ){ if (mom.width == width && mom.height == height){ float scalef = 1.0f / 255.0f; cvMul(cvImage, mom.getCvImage(), cvImageTemp, scalef); swapTemp(); } else { // what do we do? // cvResize? // cvClone? printf("error in =, images are different sizes\n"); } } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator -= ( float scalar ){ cvSubS(cvImage, cvScalar(scalar), cvImageTemp); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator += ( float scalar ){ cvAddS(cvImage, cvScalar(scalar), cvImageTemp); swapTemp(); } //------------------------------------------------------------------------------------- void ofCvGrayscaleImage::operator &= ( ofCvGrayscaleImage & mom ){ cvAnd( mom.getCvImage(), cvImage, cvImageTemp); swapTemp(); } //-------------------------------------------------------------------------------------