動動画 DOUDOUGA -3.プログラム-
processingを使って作ってみました.
ファイル構成は
- projectionMovie/projectionMovie.pde
- projectionMovie/Tool.pde
- projectionMovie/data/video.mp4
という感じ.
projectionMovie/projectionMovie.pde /** * projecting a movie using two reflection icons. * hoimei: hoimei@acm.org * 2009.08.10 **/ import processing.video.*; Movie myMovie; Capture cam; DynamicTV dytv; boolean movfrg; // you can select the camera device. int CAMERA_DEVICE_NUM = 2; // color threshold for detecting the two reflection icons. float COLOR_THRE = 100; // for crrecting the shake of the movie. int CORRECTE_SHAKE_THRE = 9; ////////////////////////////////////////////////////////////////// // SET UP ////////////////////////////////////////////////////////////////// void setup() { size(800, 600, P2D); String[] devices = Capture.list(); println(devices); cam = new Capture(this, 320, 240, devices[CAMERA_DEVICE_NUM]); dytv = new DynamicTV(); movfrg = false; background(0); } ////////////////////////////////////////////////////////////////// // DRAW ////////////////////////////////////////////////////////////////// void draw() { if (cam.available() == true) { loadPixels(); cam.read(); dytv.searchReflectiveSeal(COLOR_THRE); updatePixels(); } dytv.searchMaxMinXY(); dytv.correctShake(); dytv.calcMovSize(); if(movfrg){ // to project the movie, type the space key. dytv.display(myMovie); } //dytv.check(); } ////////////////////////////////////////////////////////////////// void keyTyped() { myMovie = new Movie(this, "video.mp4"); myMovie.loop(); movfrg = true; } void movieEvent(Movie myMovie) { myMovie.read(); }
|
---|
projectionMovie/Tool.pde class DynamicTV{ color BLACK; color BLUE; int x, y, curr, currWin; int[] Buf; float r, g, b; float br; PImage backImg; int minX, minY, maxX, maxY; int pastminX, pastminY, pastmaxX, pastmaxY; float movSizeX, movSizeY; DynamicTV(){ BLACK = color(0,0,0); BLUE = color(0, 0, 255); Buf = new int[cam.width*cam.height]; minX = pastminX = cam.width; minY = pastminY = cam.height; maxX = maxY = pastmaxX = pastmaxY = 0; movSizeX = width/10; movSizeY = height/10; backImg = createImage(width, height, RGB); backImg.loadPixels(); for(int n=0;n<width*height;n++)backImg.pixels[n] = BLACK; } void searchReflectiveSeal(float colThre){ for(y=0;y<cam.height-1;y++){ for(x=0;x<cam.width;x++){ curr = y*cam.width + x; currWin = y*width + x; r = red(cam.pixels[curr]); g = green(cam.pixels[curr]); b = blue(cam.pixels[curr]); //br = brightness(cam.pixels[curr]); if((0<x && x<cam.width-1) && (0<y && y <cam.height-1)){ if(COLOR_THRE<r && COLOR_THRE<g && COLOR_THRE<b){ //if(BRIGHT_THRE<br){ pixels[currWin] = BLUE; Buf[curr] = 1; }else{ pixels[currWin] = cam.pixels[curr]; Buf[curr] = 0; } }else{ pixels[currWin] = cam.pixels[curr]; Buf[curr] = 0; } } } } void searchMaxMinXY(){ minX = minY = maxX = maxY = -1; for(int i=0; i<cam.width*cam.height-3*cam.width; i++){ if(Buf[i]==1 && Buf[i+1]==1 && Buf[i+2]==1){ if(minX==-1){ minX = i%cam.width; }else if(maxX < i%cam.width){ maxX = i%cam.width; } } if(Buf[i]==1 && Buf[i+cam.width]==1 && Buf[i+cam.width*2]==1){ if(minY==-1){ minY = i/cam.width; }else if(maxY < i/cam.width){ maxY = i/cam.width; } } } } void correctShake(){ if((pastminX-minX)*(pastminX-minX)<CORRECTE_SHAKE_THRE){ minX = pastminX; } if((pastminY-minY)*(pastminY-minY)<CORRECTE_SHAKE_THRE){ minY = pastminY; } if((pastmaxX-maxX)*(pastmaxX-maxX)<CORRECTE_SHAKE_THRE){ maxX = pastmaxX; } if((pastmaxY-maxY)*(pastmaxY-maxY)<CORRECTE_SHAKE_THRE){ maxY = pastmaxY; } } //calculating the movie size void calcMovSize(){ if(minX != -1){ movSizeX = maxX - minX; movSizeY = maxY - minY; } } void display(Movie mov){ image(backImg, 0, 0); image(mov, minX*2.3, minY*2.3, movSizeX*3.3, movSizeY*3.3); } void check(){ println("min X = " + minX + ", min Y = " + minY); println("max X = " + maxX + ", max Y = " + maxY); println("Movie size X = "+ movSizeX); println("Movie size Y = "+ movSizeY); } }
|
---|