VideoStream Filters.cpp

From IPRE Wiki
Jump to: navigation, search
#include <Myro.h>
#include <VideoStream.h>
#include <Filter.h>
#include <iostream>
#include <string>
#include <cstring>
#include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;

Pixel black = {0,51,76};
Pixel red = {217,26,33};
Pixel blue = {112,150,158};
Pixel yellow = {252,227,166};

class InvertFilter: public Filter {
    public:
    virtual void filter(Picture * image) {
        int height = getHeight(image);
        int width = getWidth(image);

        Pixel temp;
        for(int h = 0; h < height/2; h++) {
            for(int w = 0; w < width; w++) {
                temp = getPixel(image,w,h);
                setPixel(image,w,h, getPixel(image,w,(height-1)-h));
                setPixel(image,w,(height-1)-h,temp);
            }
        }
    }
};

/*
class InvertFilter: public Filter {

    public:
    virtual void filter(Picture * image) {
        int height = image->getHeight();
        int width = image->getWidth();

        Pixel temp;
        for(int h = 0; h < height/2; h++) {
            for(int w = 0; w < width; w++) {
                temp = image->getPixel(w,h);
                image->setPixel(w,h, image->getPixel(w,(height-1)-h));
                image->setPixel(w,(height-1)-h,temp);
            }
        }
    }

    private:
};
*/

class LightMask: public Filter {
    
    public:

    virtual void filter(Picture * image) {

        //int color_mode = getColorMode();
        //if(color_mode)
        //    return;

        int imageHeight = image->getHeight();
        int imageWidth  = image->getWidth();

        int numPartitions = 4;
        int partition_width = imageWidth/numPartitions;

        int shadePartition;
        double brightEst = 0;
        int partition_sum[6] = {0,0,0,0,0,0};

        // Sum up each partition
        for(int y = 0; y < imageHeight; y++) {
            for(int partition = 0; partition < numPartitions; partition++) {
                for(int x = partition*partition_width; x < (partition+1)*partition_width; x++) {
                    //partion[j] += image[(h * imageWidth) + (h * partition_width) + k];
                    Pixel pix = image->getPixel(x,y);
                    partition_sum[partition] += pix.R + pix.G + pix.B;
                }
            }
        }

        // Determine which partition is the brightest
        shadePartition = 0;
        brightEst = partition_sum[0]/(imageHeight * partition_width);
        for(int i = 1; i < numPartitions; i++) {
            if( partition_sum[i]/(imageHeight * partition_width) > brightEst ) {
                shadePartition = i;
                brightEst = partition_sum[i]/(imageHeight * partition_width);
            }
        }

        Pixel black = {0,0,0};
        // Make every region thats not the drawn one black
        for(int y = 0; y < imageHeight; y++) {
            for(int partition = 0; partition < numPartitions; partition++) {
                if ( partition != shadePartition ){
                    for(int x = partition*partition_width; x < (partition+1)*partition_width; x++) {
                        image->setPixel(x,y,black);
                    }
                }
            }
        }
    }
};

class ObamaIconFilter : public Filter {
    public:
    virtual void filter(Picture * image) {
        int height = image->getHeight();
        int width = image->getWidth();

        Pixel temp;
        int intensity=0;
        for(int h = 0; h < height; h++) {
            for(int w = 0; w < width; w++) {
                temp = image->getPixel(w,h);
                intensity = (temp.R+temp.G+temp.B)/3;
                if ( intensity > 182 )
                    image->setPixel(w,h,yellow);
                else if ( intensity > 121 )
                    image->setPixel(w,h,blue);
                else if ( intensity > 60 )
                    image->setPixel(w,h,red);
                else
                    image->setPixel(w,h,black);
            }
        }
    }
};

class RedHue : public Filter{
    public:
    virtual void filter(Picture* image){
        int height = image->getHeight();
        int width = image->getWidth();
        Pixel temp;
        for(int h = 0; h < height; h++) {
            for(int w = 0; w < width; w++){
                temp = getPixel(image,w,h);
                temp.R = 255;
                setPixel(image,w,h,temp);
            }
        }
    }
};

class BlackAndWhite : public Filter{
    virtual void filter(Picture* image){
        int height = image->getHeight();
        int width = image->getWidth();

        Pixel temp;
        int intensity=0;
        for(int h = 0; h < height; h++) {
            for(int w = 0; w < width; w++) {
                temp = getPixel(image,w,h);
                intensity = (temp.R+temp.G+temp.B)/3;
                setPixelColor(image,w,h,intensity,intensity,intensity);
            }
        }
    }
};

int main(){
    connect();
    VideoStream vs(robot,1);
    vs.startStream();
    ObamaIconFilter * ob = new ObamaIconFilter();
    InvertFilter * inv = new InvertFilter();
    LightMask * lm = new LightMask();
    RedHue * rh = new RedHue();
    BlackAndWhite * bw = new BlackAndWhite();
    int applied_filters = 0;
    int selection = -1;
    int index = 0;
    while ( selection != 0 ){
        cout << "Menu: " << endl
             << "1) Add ObamIcon Filter" << endl
             << "2) Add Invert Filter" << endl
             << "3) Add LightMask Filter" << endl
             << "4) Add Red Hue Filter" << endl
             << "5) Add Black & White Filter" << endl
             << "6) Clear Filters" << endl
             << "0) Exit" << endl
             << endl;
        cin >> selection;
        switch(selection){
        case 1:
            index = vs.addFilter(ob);
            applied_filters++;
            break;
        case 2:
            index = vs.addFilter(inv);
            applied_filters++;
            break;
        case 3:
            index = vs.addFilter(lm);
            applied_filters++;
            break;
        case 4:
            index = vs.addFilter(rh);
            applied_filters++;
            break;
        case 5:
            index = vs.addFilter(bw);
            applied_filters++;
            break;
        case 6:
        case 0:
            for (int i = 0; i < applied_filters; i++){
                vs.delFilter(0);
            }
            applied_filters = 0;
            break;
        default:
            cout << "Invalid Input: " << selection << endl;
            continue;
        }
        if ( selection == 0 ){
            break;
        }
    }
    vs.endStream();
    cout << "goodbye!" << endl;

    disconnect();
}