diff options
Diffstat (limited to 'rotord/src/cvimage.cpp')
| -rw-r--r-- | rotord/src/cvimage.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/rotord/src/cvimage.cpp b/rotord/src/cvimage.cpp new file mode 100644 index 0000000..c18c585 --- /dev/null +++ b/rotord/src/cvimage.cpp @@ -0,0 +1,156 @@ +#include "cvimage.h" + +using namespace std; + +namespace Rotor { + Image & Image::operator+=(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + rgb+=other.rgb; + } + return *this; + } + Image & Image::operator*=(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot multiply images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + //rgb/=other.rgb; //does funny glitchy stuff + //could use cv::Mat.mul() here + for (int i=0;i<w*h*3;i++){ + //calculate with tables + rgb.data[i]=pixels.multiply[rgb.data[i]][other.rgb.data[i]]; + } + } + return *this; + } + Image & Image::operator^=(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + rgb^=other.rgb; + } + return *this; + } + Image & Image::add_wrap(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + for (int i=0;i<w*h*3;i++){ + //creates rainbow overload, openCV doesn't do this + rgb.data[i]=(unsigned char)(((int)other.rgb.data[i]+(int)rgb.data[i])); + } + } + return *this; + } + Image & Image::divide_wrap(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + for (int i=0;i<w*h*3;i++){ + //creates rainbow overload, openCV doesn't do this + rgb/=other.rgb; //does funny glitchy stuff + } + } + return *this; + } + //THIS OPENCV VERSION IS SLOWER THAN THE OLDSKOOL VERSION BELOW + Image & Image::alpha_blend_cv(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot blend images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + //why not?? + } + else if (!other.alpha.data){ + //default to full on alpha + rgb=other.rgb.clone(); + } + else { + //overlay the other image based on its alpha values + //https://gist.github.com/Brick85/5009046 - this is a dumb way to do it? + //how to invert a matrix? + //'invert' is matrix invert - different + //subtract from a scalar (1) ? + vector<cv::Mat> ichans,ochans; + vector<cv::Mat> compchans; + cv::split(rgb,ichans); + cv::split(other.rgb,ochans); + uint8_t b=0xFF; + cv::Mat iA=b-other.alpha; + for (int i=0;i<3;i++) { + compchans.push_back(ichans[i].mul(iA,1.0/255.0)+ochans[i].mul(other.alpha,1.0/255.0)); + } + merge(compchans,rgb); + //rgb+=other.rgb; + //for (int i=0;i<w*h*3;i++) { + // rgb.data[i]=(uint8_t)(((((int)rgb.data[i])*(0xFF-other.alpha.data[i/3]))>>8)+((((int)other.rgb.data[i])*((int)other.alpha.data[i/3]))>>8)); + //} + } + + return *this; + } + Image & Image::alpha_blend(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot blend images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + //why not?? + } + else if (!other.alpha.data){ + //default to full on alpha + rgb=other.rgb.clone(); + } + else { + for (int i=0;i<w*h*3;i++) { + rgb.data[i]=(uint8_t)(((((int)rgb.data[i])*(0xFF-other.alpha.data[i/3]))>>8)+((((int)other.rgb.data[i])*((int)other.alpha.data[i/3]))>>8)); + } + } + return *this; + } + Image & Image::alpha_merge(const Image &other) { + //converts the incoming image to monochrome and inserts it into the alpha channel of this image + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot merge alpha with different size! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + cv::cvtColor(other.rgb,alpha,CV_RGB2GRAY); + } + return *this; + } + //channel rearrangement + //RGBAZ - these are channels 0-4 + //HSB - can also have these virtual channels 5-7 + //convert channels- int outChannel[5] - {0,1,2,-5,4} - this mapping sends inverted brightness to alpha + + //scalar operations allocate a new image. + //maybe this could not be the case if the data is owned by this image? + //need to look into auto_ptr + Image & Image::operator*=(const float &amount) { + rgb*=amount; + return *this; + } + Image * Image::operator*(const float &amount) { + Image *other=new Image(w,h); + other->rgb=rgb*amount; + return other; + } + Image * Image::operator+(const float &amount) { + uint8_t amt=(uint8_t)(amount*255.0f); + Image *other=new Image(w,h); + other->rgb=rgb+amt; + return other; + } + Image * Image::operator-(const float &amount) { + uint8_t amt=(uint8_t)(amount*255.0f); + Image *other=new Image(w,h); + other->rgb=rgb-amt; + return other; + } + Image * Image::operator/(const float &amount) { + Image *other=new Image(w,h); + other->rgb=rgb/amount; + return other; + } +} |
