//import processing.opengl.*; // Mirror images processing // Reflection reMapping // // @ TODO //~ Speed up analysis //~ To have the background changes only effect //~ Look up blobfinding in //~ http://webcamxtra.sourceforge.net/ //~ http://v3ga.net/processing/BlobDetection/Library/ // // this text goes out to html /** press d to display an image * press f to flatten the mirrors press i to swap background * press l to swap content */ // setup webCam input // import processing.video.*; //~ import processing.opengl.*; // Capture camCapture; //~ Capture analysisCapture; // image variables int imageWidth = 800; int imageHeight = 600; int totalScale = 1; // simply scale the output on the screen, use natural numbers PImage mirrorImage; PImage displayImage; PImage canvasImage = new PImage(imageWidth * totalScale, imageHeight * totalScale); int[] imagePixels; int imagePixelAmount = imageWidth * imageHeight; int mirrorImageSetSize = 5; // amont of available images as backgrounds int currentmirrorImage = 0; // counter for loading the above int contentImageSetSize = 5; // amont of available images to display int currentContentImage = 0; // counter for loading the above // displayImage int displayImageWidth = 40; // init segments (mirrors) int mirrorWidth = 20; // has to be while divideable with imageWidth int mirrorHeight = 20; // hes to be whole divideable with imageHeigth PImage mirrorAnalysisImage = new PImage(imageWidth / mirrorWidth, imageHeight - mirrorHeight); float[][] coloumnBrigthness; //for storing mirror average brightness, 0-100 float[][] coloumnBlankBrigthness; //for storing mirror average brightness, 0-100 float[][] coloumnHue; //for storing mirror average hue, 0-100 float[][] coloumnSaturation; //for storing mirror average sat, 0-100 float[][] targetBrightness; // for storing the image brigthness we want to display, 0-100 float[][] targetHue; // for storing the image hue we want to display, 0-100 float[][] targetSaturation; // for storing the image sat we want to display, 0-100 int mirrorView[][]; // where a coloumn / row mirror is looking at, defining its angle, and image offset int mirrorFlatView[][]; // where a coloumn / row mirror is looking at if reset to zero offset float rotationSpeed = 20; // flags and counters int coloumn = 0; int row = 0; boolean runOnce = false; boolean showDisplayImage = false; boolean showFlat = true; boolean gotSnapshot = false; boolean useTelePort = false; // setup global options void setup(){ size(820, 620, P3D); colorMode(HSB, 100); background(50); frameRate(25); // webcam setup // to find out your camera name, uncomment the following line //~ println(Capture.list()); //~ String webCamName = "Labtec WebCam-WDM"; //~ String webCamName = "Microsoft DV Camera and VCR-WDM"; // String webCamName = "Creative WebCam Notebook-WDM"; //~ String webCamName = "USB videoeszk�z-WDM"; //~ camCapture = new Capture(this, webCamName, imageWidth, imageHeight, 25); // to draw the grid stroke(0, 20); strokeWeight(1); } // looping main void draw(){ if (!runOnce){ initArrays(); resetViewArrayValues(); initImage(); loadDisplayImage(); runOnce = true; } //~ initImage(); //~ readCamera(); rotateMirrors(); drawMirrors(); drawGrid(); //~ displayAnalysis(); //~ saveFrame("alephvideomirror-#####.tif"); } // init Arrays void initArrays(){ // new arrays with size imagePixels = new int[imagePixelAmount]; coloumnBrigthness = new float[(imageWidth / mirrorWidth)][imageHeight]; coloumnBlankBrigthness = new float[(imageWidth / mirrorWidth)][imageHeight]; coloumnHue = new float[(imageWidth / mirrorWidth)][imageHeight]; coloumnSaturation = new float[(imageWidth / mirrorWidth)][imageHeight]; targetBrightness = new float[(imageWidth / mirrorWidth)][imageHeight / mirrorHeight]; targetHue = new float[(imageWidth / mirrorWidth)][imageHeight / mirrorHeight]; targetSaturation = new float[(imageWidth / mirrorWidth)][imageHeight / mirrorHeight]; mirrorFlatView = new int[(imageWidth / mirrorWidth)][imageHeight / mirrorHeight]; mirrorView = new int[(imageWidth / mirrorWidth)][imageHeight / mirrorHeight]; } void resetViewArrayValues(){ // place initial array content for (coloumn = 0; coloumn < imageWidth / mirrorWidth; coloumn++){ for (row = 0; row < imageHeight / mirrorHeight; row++){ mirrorFlatView[coloumn][row] = (mirrorHeight / 2) + (row * mirrorHeight); mirrorView[coloumn][row] = (mirrorHeight / 2) + (row * mirrorHeight); } } saveBackgroundSnapshot(); } // draw Grid void drawGrid(){ //~ stroke(0, 20); //~ strokeWeight(1); for (int i=0; i<(imageWidth / mirrorWidth); i++){ line(10 + i * mirrorWidth * totalScale, 10, i * mirrorWidth * totalScale+ 10, imageHeight * totalScale - mirrorHeight * totalScale+ 10); } for (int i=0; i<(imageHeight / mirrorHeight); i++){ line(10, 10 + i * mirrorHeight * totalScale, imageWidth * totalScale - mirrorWidth * totalScale+ 10, i * mirrorHeight * totalScale+ 10); } } // get background image or CAM image void initImage(){ mirrorImage = loadImage("testimage"+currentmirrorImage+".jpg"); if (currentmirrorImage < mirrorImageSetSize - 1){ currentmirrorImage++; } else { currentmirrorImage = 0; } //~ camCapture.read(); //~ mirrorImage = camCapture; for(int i=0; i10){ coloumnBrigthness[i][j] = tempBright; } } } } void displayAnalysis(){ for (int i=0; i<(imageWidth / mirrorWidth); i++){ for (int j=0; j 60 && gotSnapshot && false){ hitPosition = (mirrorHeight / 2) + (row * mirrorHeight); } else if (abs(coloumnBrigthness[coloumn][coloumnHeight] - target) < distance){ distance = abs(coloumnBrigthness[coloumn][coloumnHeight] - target); hitPosition = coloumnHeight; }; } // iterate to closest value if ((mirrorView[coloumn][row] - hitPosition) > rotationSpeed){ //~ mirrorView[coloumn][row] -= int((mirrorView[coloumn][row] - hitPosition)/rotationSpeed); mirrorView[coloumn][row] -= rotationSpeed; } else if ((mirrorView[coloumn][row] - hitPosition) < -rotationSpeed){ mirrorView[coloumn][row] += rotationSpeed; } else { //~ mirrorView[coloumn][row] = hitPosition; mirrorView[coloumn][row] = hitPosition; } } else { if ((mirrorView[coloumn][row] - mirrorFlatView[coloumn][row]) > rotationSpeed){ mirrorView[coloumn][row] -= rotationSpeed; //~ mirrorView[coloumn][row] -= int((mirrorView[coloumn][row] - mirrorFlatView[coloumn][row])/ //~ rotationSpeed); } else if ((mirrorView[coloumn][row] - mirrorFlatView[coloumn][row]) < -rotationSpeed) { mirrorView[coloumn][row] += rotationSpeed; } else { mirrorView[coloumn][row] = mirrorFlatView[coloumn][row]; } } } } }; // draw Mirrors void drawMirrors(){ for (coloumn = 0; coloumn < imageWidth / mirrorWidth - 1; coloumn++){ for (row = 0; row < imageHeight / mirrorHeight - 1; row++){ canvasImage.copy(mirrorImage,coloumn*mirrorWidth,mirrorView[coloumn][row],mirrorWidth,mirrorHeight, coloumn*mirrorWidth*totalScale,row*mirrorHeight*totalScale,mirrorWidth*totalScale,mirrorHeight*totalScale); } } set(10, 10, canvasImage); } // get brigthness for a mirror sized area float getMirrorBrigthness(int position){ position -= (mirrorWidth / 2) + (imageWidth * (mirrorHeight / 2)); float addedBrigthness = 0; for (int i=0; i