#include "ofxCvGrayscaleImage.h"
#include "ofxCvColorImage.h"
#include "ofxCvFloatImage.h"
#include "ofxCvShortImage.h"
ofxCvGrayscaleImage::ofxCvGrayscaleImage() {
init();
}
ofxCvGrayscaleImage::~ofxCvGrayscaleImage(){
cvReleaseMat(&briConLutMatrix);
}
ofxCvGrayscaleImage::ofxCvGrayscaleImage( const ofxCvGrayscaleImage& _mom ) {
init();
if( _mom.bAllocated ) {
ofxCvGrayscaleImage& mom = const_cast<ofxCvGrayscaleImage&>(_mom);
allocate( (int)mom.getWidth(), (int)mom.getHeight() );
cvCopy( mom.getCvImage(), cvImage, 0 );
} else {
ofLogNotice("ofxCvGrayscaleImage") << "copy constructor: source image not allocated";
}
}
void ofxCvGrayscaleImage::init() {
ipldepth = IPL_DEPTH_8U;
iplchannels = 1;
briConLutMatrix = cvCreateMat(1,256,CV_8UC1);
}
void ofxCvGrayscaleImage::allocateTexture(){
tex.allocate(pixels);
}
void ofxCvGrayscaleImage::allocatePixels(int w, int h){
pixels.allocate(w,h,OF_PIXELS_GRAY);
}
void ofxCvGrayscaleImage::set( float value ){
if( !bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "set(): image not allocated";
return;
}
cvSet(cvImage, cvScalar(value));
flagImageChanged();
}
void ofxCvGrayscaleImage::setFromPixels( const unsigned char* _pixels, int w, int h ) {
if( w == 0 || h == 0 ){
ofLogError("ofxCvGrayscaleImage") << "setFromPixels(): width and height are zero";
return;
}
if( !bAllocated || w != width || h != height ) {
if ( !bAllocated ){
ofLogNotice("ofxCvGrayscaleImage") << "setFromPixels(): allocating to match dimensions: "
<< width << " " << height;
}else{
ofLogNotice("ofxCvGrayScaleImage") << "setFromPixels(): reallocating to match dimensions: "
<< width << " " << height;
}
allocate(w,h);
}
if( w == width && h == height ) {
if( cvImage->width == cvImage->widthStep ){
memcpy( cvImage->imageData, _pixels, w*h);
}else{
for( int i=0; i < height; i++ ) {
memcpy( cvImage->imageData + (i*cvImage->widthStep),
_pixels + (i*w),
width);
}
}
flagImageChanged();
} else {
ofLogError("ofxCvFloatImage") << "setFromPixels(): image size mismatch";
}
}
void ofxCvGrayscaleImage::setRoiFromPixels( const unsigned char* _pixels, int w, int h ) {
if( w == 0 || h == 0 ){
ofLogError("ofxCvFloatImage") << "setRoiFromPixels(): width and height are zero";
return;
}
if(!bAllocated){
ofLogError("ofxCvGrayscaleImage") << "setRoiFromPixels(): image not allocated";
return;
}
ofRectangle roi = getROI();
ofRectangle inputROI = ofRectangle( roi.x, roi.y, w, h);
ofRectangle iRoi = getIntersectionROI( roi, inputROI );
if( iRoi.width > 0 && iRoi.height > 0 ) {
for( int i=0; i < iRoi.height; i++ ) {
memcpy( cvImage->imageData + ((i+(int)iRoi.y)*cvImage->widthStep) + (int)iRoi.x,
_pixels + (i*w),
(int)(iRoi.width));
}
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "setRoiFromPixels(): region of interest width and/or height are zero: "
<< iRoi.width << " " << iRoi.height;
}
}
void ofxCvGrayscaleImage::operator = ( const ofPixels & _pixels ) {
setFromPixels( _pixels);
}
void ofxCvGrayscaleImage::operator = ( const ofxCvGrayscaleImage& _mom ) {
if(this != &_mom) {
ofxCvGrayscaleImage& mom = const_cast<ofxCvGrayscaleImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvGrayscaleImage") << "operator=: source width and/or height are zero: "
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvGrayscaleImage") << "operator=: allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
cvCopy( mom.getCvImage(), cvImage, 0 );
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "operator=: region of interest mismatch";
}
} else {
ofLogWarning("ofxCvGrayscaleImage") << "operator=: assigning image to itself, not copying";
}
}
void ofxCvGrayscaleImage::operator = ( const ofxCvColorImage& _mom ) {
ofxCvColorImage& mom = const_cast<ofxCvColorImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvGrayscaleImage") << "operator=: source width and/or height are zero:"
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvGrayscaleImage") << "operator=: allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
cvCvtColor( mom.getCvImage(), cvImage, CV_RGB2GRAY );
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "operator=: region of interest mismatch";
}
}
void ofxCvGrayscaleImage::operator = ( const ofxCvFloatImage& _mom ) {
ofxCvFloatImage& mom = const_cast<ofxCvFloatImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvGrayscaleImage") << "operator=: source width and/or height are zero:"
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvGrayscaleImage") << "operator=: allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
rangeMap( mom.getCvImage(), cvImage,
mom.getNativeScaleMin(), mom.getNativeScaleMax(), 0, 255.0f );
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "operator=: region of interest mismatch";
}
}
void ofxCvGrayscaleImage::operator = ( const ofxCvShortImage& _mom ) {
ofxCvShortImage& mom = const_cast<ofxCvShortImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvGrayscaleImage") << "operator=: source width and/or height are zero:"
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvGrayscaleImage") << "operator=: allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
rangeMap( mom.getCvImage(), cvImage, 0, 65535.0f, 0, 255.0f );
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "operator=: region of interest mismatch";
}
}
void ofxCvGrayscaleImage::operator = ( const IplImage* _mom ) {
ofxCvImage::operator = (_mom);
}
void ofxCvGrayscaleImage::absDiff( ofxCvGrayscaleImage& mom ){
if( !mom.bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "absDiff(): source image not allocated";
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvGrayscaleImage") << "absDiff(): allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
cvAbsDiff( cvImage, mom.getCvImage(), cvImageTemp );
swapTemp();
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "absDiff(): region of interest mismatch";
}
}
void ofxCvGrayscaleImage::absDiff( ofxCvGrayscaleImage& mom,
ofxCvGrayscaleImage& dad ) {
if( !mom.bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "absDiff(): first source image (mom) not allocated";
return;
}
if( !dad.bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "absDiff(): second source image (dad) not allocated";
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvGrayscaleImage") << "absDiff(): allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
ofRectangle roi = getROI();
ofRectangle momRoi = mom.getROI();
ofRectangle dadRoi = dad.getROI();
if( (momRoi.width == roi.width && momRoi.height == roi.height ) &&
(dadRoi.width == roi.width && dadRoi.height == roi.height ) )
{
cvAbsDiff( mom.getCvImage(), dad.getCvImage(), cvImage );
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "absDiff(): source image size mismatch between first (mom) & second (dad) image";
}
}
void ofxCvGrayscaleImage::contrastStretch() {
if( !bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "contrastStretch(): image not allocated";
return;
}
double minVal, maxVal;
cvMinMaxLoc( cvImage, &minVal, &maxVal, NULL, NULL, 0 );
rangeMap( cvImage, minVal,maxVal, 0,255 );
flagImageChanged();
}
void ofxCvGrayscaleImage::convertToRange(float min, float max ){
if( !bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "convertToRange(): image not allocated";
return;
}
rangeMap( cvImage, 0, 255, min, max);
flagImageChanged();
}
void ofxCvGrayscaleImage::threshold( int value, bool invert){
if( !bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "threshold(): image not allocated";
return;
}
int type = invert ? CV_THRESH_BINARY_INV : CV_THRESH_BINARY;
cvThreshold(cvImage, cvImage, value, 255, type);
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::brightnessContrast(float brightness, float contrast){
if( !bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "brightnessContrast(): image not allocated";
return;
}
int i;
double delta;
double a;
double b;
if( contrast > 0 )
{
delta = 127.*contrast;
a = 255./(255. - delta*2);
b = a*(brightness*100 - delta);
}else{
delta = -128.*contrast;
a = (256.-delta*2)/255.;
b = a*brightness*100. + delta;
}
for( i = 0; i < 256; i++ )
{
int v = cvRound(a*i + b);
if( v < 0 )
v = 0;
if( v > 255 )
v = 255;
briConLutMatrix->data.ptr[i] = (uchar)v;
}
cvLUT( cvImage, cvImageTemp, briConLutMatrix);
swapTemp();
flagImageChanged();
}
void ofxCvGrayscaleImage::resize( int w, int h ) {
if( !bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "resize(): image not allocated";
return;
}
IplImage* temp = cvCreateImage( cvSize(w,h), IPL_DEPTH_8U, 1 );
cvResize( cvImage, temp );
clear();
allocate( w, h );
cvCopy( temp, cvImage );
cvReleaseImage( &temp );
}
void ofxCvGrayscaleImage::scaleIntoMe( ofxCvImage& mom, int interpolationMethod ){
if( !bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "scaleIntoMe(): image not allocated";
return;
}
if( !mom.bAllocated ){
ofLogError("ofxCvGrayscaleImage") << "scaleIntoMe(): source image not allocated";
return;
}
if( mom.getCvImage()->nChannels == cvImage->nChannels &&
mom.getCvImage()->depth == cvImage->depth ) {
if ((interpolationMethod != CV_INTER_NN) &&
(interpolationMethod != CV_INTER_LINEAR) &&
(interpolationMethod != CV_INTER_AREA) &&
(interpolationMethod != CV_INTER_CUBIC) ){
ofLogWarning("ofxCvGrayscaleImage") << "scaleIntoMe(): setting interpolationMethod to CV_INTER_NN";
interpolationMethod = CV_INTER_NN;
}
cvResize( mom.getCvImage(), cvImage, interpolationMethod );
flagImageChanged();
} else {
ofLogError("ofxCvGrayscaleImage") << "scaleIntoMe(): type mismatch with source image";
}
}
Comments