#include "ofxCvGrayscaleImage.h"
#include "ofxCvColorImage.h"
#include "ofxCvFloatImage.h"
#include "ofxCvShortImage.h"
ofxCvColorImage::ofxCvColorImage() {
init();
}
ofxCvColorImage::ofxCvColorImage( const ofxCvColorImage& _mom ) {
init();
if( _mom.bAllocated ) {
ofxCvColorImage& mom = const_cast<ofxCvColorImage&>(_mom);
allocate( (int)mom.getWidth(), (int)mom.getHeight() );
cvCopy( mom.getCvImage(), cvImage, 0 );
} else {
ofLogWarning("ofxCvColorImage") << "copy constructor: source image not allocated";
}
}
void ofxCvColorImage::allocateTexture(){
tex.allocate(pixels);
}
void ofxCvColorImage::allocatePixels(int w, int h){
pixels.allocate(w,h,OF_PIXELS_RGB);
}
void ofxCvColorImage::init() {
ipldepth = IPL_DEPTH_8U;
iplchannels = 3;
cvGrayscaleImage = NULL;
}
void ofxCvColorImage::clear() {
if (bAllocated == true && cvGrayscaleImage != NULL){
cvReleaseImage( &cvGrayscaleImage );
}
ofxCvImage::clear();
}
void ofxCvColorImage::set( float value ){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "set(): image not allocated";
return;
}
cvSet(cvImage, cvScalar(value, value, value));
flagImageChanged();
}
void ofxCvColorImage::set(int valueR, int valueG, int valueB){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "set(): image not allocated";
return;
}
cvSet(cvImage, cvScalar(valueR, valueG, valueB));
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 ofxCvColorImage::operator += ( float value ) {
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "set(): image not allocated";
return;
}
cvAddS( cvImage, cvScalar(value, value, value), cvImageTemp );
swapTemp();
flagImageChanged();
}
void ofxCvColorImage::setFromPixels( const unsigned char* _pixels, int w, int h ) {
if( w == 0 || h == 0 ){
ofLogError("ofxCvColorImage") << "setFromPixels(): width and height are zero";
return;
}
if( !bAllocated || w != width || h != height ) {
if ( !bAllocated ){
ofLogNotice("ofxCvColorImage") << "setFromPixels(): allocating to match dimensions: "
<< width << " " << height;
}else{
ofLogNotice("ofxCvColorImage") << "setFromPixels(): reallocating to match dimensions: "
<< width << " " << height;
}
allocate(w,h);
}
if( cvImage->width*cvImage->nChannels == cvImage->widthStep ){
memcpy( cvImage->imageData, _pixels, w*h*iplchannels);
}else{
for( int i=0; i < height; i++ ) {
memcpy( cvImage->imageData + (i*cvImage->widthStep), _pixels + (i*w*iplchannels),width*iplchannels );
}
}
flagImageChanged();
}
void ofxCvColorImage::setRoiFromPixels( const unsigned char* _pixels, int w, int h ) {
if( w == 0 || h == 0 ){
ofLogError("ofxCvColorImage") << "setRoiFromPixels(): width and height are zero";
return;
}
if(!bAllocated){
ofLogError("ofxCvColorImage") << "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*iplchannels,
_pixels + (i*w*iplchannels),
(int)(iRoi.width*iplchannels) );
}
flagImageChanged();
} else {
ofLogError("ofxCvColorImage") << "setRoiFromPixels(): region of interest width and/or height are zero: "
<< iRoi.width << " " << iRoi.height;
}
}
void ofxCvColorImage::setFromGrayscalePlanarImages( ofxCvGrayscaleImage& red, ofxCvGrayscaleImage& green, ofxCvGrayscaleImage& blue){
ofRectangle roi = getROI();
ofRectangle redRoi = red.getROI();
ofRectangle greenRoi = green.getROI();
ofRectangle blueRoi = blue.getROI();
if( !bAllocated ){
ofLogNotice("ofxCvColorImage") << "setFromGrayscalePlanarImages(): allocating to match dimensions";
allocate(red.getWidth(), red.getHeight());
}
if( redRoi.width == roi.width && redRoi.height == roi.height &&
greenRoi.width == roi.width && greenRoi.height == roi.height &&
blueRoi.width == roi.width && blueRoi.height == roi.height )
{
cvMerge(red.getCvImage(), green.getCvImage(), blue.getCvImage(),NULL, cvImage);
flagImageChanged();
} else {
ofLogError("ofxCvColorImage") << "setFromGrayscalePlanarImages(): image size or region of interest mismatch";
}
}
void ofxCvColorImage::operator = ( const ofPixels & _pixels ) {
setFromPixels( _pixels );
}
void ofxCvColorImage::operator = ( const ofxCvGrayscaleImage& _mom ) {
ofxCvGrayscaleImage& mom = const_cast<ofxCvGrayscaleImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvColorImage") << "operator=: source width and/or height are zero: "
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvColorImage") << "operator=: allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
cvCvtColor( mom.getCvImage(), cvImage, CV_GRAY2RGB );
flagImageChanged();
} else {
ofLogError("ofxCvColorImage") << "operator=: region of interest mismatch";
}
}
void ofxCvColorImage::operator = ( const ofxCvColorImage& _mom ) {
if(this != &_mom) {
ofxCvColorImage& mom = const_cast<ofxCvColorImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvColorImage") << "operator=: source width and/or height are zero:"
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvColorImage") << "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("ofxCvColorImage") << "operator=: region of interest mismatch";
}
} else {
ofLogWarning("ofxCvColorImage") << "operator=: assigning image to itself, not copying";
}
}
void ofxCvColorImage::operator = ( const ofxCvFloatImage& _mom ) {
ofxCvFloatImage& mom = const_cast<ofxCvFloatImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvColorImage") << "operator=: source width and/or height are zero:"
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvColorImage") << "operator=: allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
if( cvGrayscaleImage == NULL ) {
cvGrayscaleImage = cvCreateImage( cvSize(width,height), IPL_DEPTH_8U, 1 );
}
ofRectangle roi = getROI();
setImageROI(cvGrayscaleImage, roi);
rangeMap( mom.getCvImage(), cvGrayscaleImage,
mom.getNativeScaleMin(), mom.getNativeScaleMax(), 0, 255.0f );
cvCvtColor( cvGrayscaleImage, cvImage, CV_GRAY2RGB );
flagImageChanged();
} else {
ofLogError("ofxCvColorImage") << "operator=: region of interest mismatch";
}
}
void ofxCvColorImage::operator = ( const ofxCvShortImage& _mom ) {
ofxCvShortImage& mom = const_cast<ofxCvShortImage&>(_mom);
if( mom.getWidth() == 0 || mom.getHeight() == 0 ){
ofLogError("ofxCvColorImage") << "operator=: source width and/or height are zero:"
<< mom.getWidth() << " " << mom.getHeight();
return;
}
if( !bAllocated ){
ofLogNotice("ofxCvColorImage") << "operator=: allocating to match dimensions: "
<< mom.getWidth() << " " << mom.getHeight();
allocate(mom.getWidth(), mom.getHeight());
}
if( matchingROI(getROI(), mom.getROI()) ) {
if( cvGrayscaleImage == NULL ) {
cvGrayscaleImage = cvCreateImage( cvSize(width,height), IPL_DEPTH_8U, 1 );
}
ofRectangle roi = getROI();
setImageROI(cvGrayscaleImage, roi);
rangeMap( mom.getCvImage(), cvGrayscaleImage, 0, 65535.0f, 0, 255.0f );
cvCvtColor( cvGrayscaleImage, cvImage, CV_GRAY2RGB );
flagImageChanged();
} else {
ofLogError("ofxCvColorImage") << "operator=: region of interest mismatch";
}
}
void ofxCvColorImage::operator = ( const IplImage* _mom ) {
ofxCvImage::operator = (_mom);
}
void ofxCvColorImage::convertToGrayscalePlanarImages(ofxCvGrayscaleImage& red, ofxCvGrayscaleImage& green, ofxCvGrayscaleImage& blue){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "convertToGrayscalePlanarImages(): image not allocated";
return;
}
ofRectangle roi = getROI();
ofRectangle redRoi = red.getROI();
ofRectangle greenRoi = green.getROI();
ofRectangle blueRoi = blue.getROI();
if( !red.bAllocated ){
red.allocate(width, height);
}
if( !green.bAllocated ){
green.allocate(width, height);
}
if( !blue.bAllocated ){
blue.allocate(width, height);
}
if( redRoi.width == roi.width && redRoi.height == roi.height &&
greenRoi.width == roi.width && greenRoi.height == roi.height &&
blueRoi.width == roi.width && blueRoi.height == roi.height )
{
cvSplit(cvImage, red.getCvImage(), green.getCvImage(), blue.getCvImage(), NULL);
red.flagImageChanged();
green.flagImageChanged();
blue.flagImageChanged();
} else {
ofLogError("ofxCvColorImage") << "convertToGrayscalePlanarImages(): image size or region of interest mismatch";
}
}
void ofxCvColorImage::convertToGrayscalePlanarImage (ofxCvGrayscaleImage& grayImage, int whichPlane){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "convertToGrayscalePlanarImage(): image not allocated";
return;
}
if( !grayImage.bAllocated ){
grayImage.allocate(width, height);
}
ofRectangle roi = getROI();
ofRectangle grayRoi = grayImage.getROI();
if( grayRoi.width == roi.width && grayRoi.height == roi.height ){
switch (whichPlane){
case 0:
cvSplit(cvImage, grayImage.getCvImage(), NULL, NULL, NULL);
grayImage.flagImageChanged();
break;
case 1:
cvSplit(cvImage, NULL, grayImage.getCvImage(), NULL, NULL);
grayImage.flagImageChanged();
break;
case 2:
cvSplit(cvImage, NULL, NULL, grayImage.getCvImage(), NULL);
grayImage.flagImageChanged();
break;
}
} else {
ofLogError("ofxCvColorImage") << "convertToGrayscalePlanarImages(): image size or region of interest mismatch";
}
}
void ofxCvColorImage::contrastStretch() {
ofLogWarning("ofxCvColorImage") << "contrastStretch(): not implemented";
}
void ofxCvColorImage::convertToRange(float min, float max ){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "convertToRange(): image not allocated";
return;
}
rangeMap( cvImage, 0,255, min,max);
flagImageChanged();
}
void ofxCvColorImage::resize( int w, int h ) {
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "resize(): image not allocated";
return;
}
IplImage* temp = cvCreateImage( cvSize(w,h), IPL_DEPTH_8U, iplchannels );
cvResize( cvImage, temp );
clear();
allocate( w, h );
cvCopy( temp, cvImage );
cvReleaseImage( &temp );
}
void ofxCvColorImage::scaleIntoMe( ofxCvImage& mom, int interpolationMethod ){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "resize(): image not allocated";
return;
}
if( !mom.bAllocated ){
ofLogError("ofxCvColorImage") << "resize(): 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("ofxCvColorImage") << "scaleIntoMe(): setting interpolationMethod to CV_INTER_NN";
interpolationMethod = CV_INTER_NN;
}
cvResize( mom.getCvImage(), cvImage, interpolationMethod );
flagImageChanged();
} else {
ofLogError("ofxCvColorImage") << "scaleIntoMe(): type mismatch with source image";
}
}
void ofxCvColorImage::convertRgbToHsv(){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "convertRgbToHsv(): image not allocated";
return;
}
cvCvtColor( cvImage, cvImageTemp, CV_RGB2HSV);
swapTemp();
flagImageChanged();
}
void ofxCvColorImage::convertHsvToRgb(){
if( !bAllocated ){
ofLogError("ofxCvColorImage") << "convertHsvToRgb(): image not allocated";
return;
}
cvCvtColor( cvImage, cvImageTemp, CV_HSV2RGB);
swapTemp();
flagImageChanged();
}
Comments