突然兴起想玩一下抠图,试着用自带的Example\video来改,花了一个中午做了个小样:
分别是白色为底与黑色为底的效果,代码如下:
1 import processing.video.*; 2 int numPixels; 3 int[] backgroundPixels; 4 Capture video; 5 PImage img; 6 7 void setup() { 8 size(640, 480); 9 video = new Capture(this, width, height); 10 video.start(); 11 numPixels = video.width * video.height; 12 backgroundPixels = new int[numPixels]; 13 img = new PImage(video.width, video.height);//make a copy of video. 14 frameRate(30); 15 } 16 17 void draw() { 18 if (video.available()) { 19 video.read(); 20 } 21 img = video;//use img as a template 22 img.loadPixels(); 23 for (int i = 0; i < numPixels; i++) { 24 color currColor = img.pixels[i]; 25 color bkgdColor = backgroundPixels[i]; 26 int currR = (currColor >> 16) & 0xFF; 27 int currG = (currColor >> 8) & 0xFF; 28 int currB = currColor & 0xFF; 29 int bkgdR = (bkgdColor >> 16) & 0xFF; 30 int bkgdG = (bkgdColor >> 8) & 0xFF; 31 int bkgdB = bkgdColor & 0xFF; 32 int diffR = abs(currR - bkgdR); 33 int diffG = abs(currG - bkgdG); 34 int diffB = abs(currB - bkgdB); 35 int td = 20;//set threshold to 20 pixcels; 36 37 //check each pixel of the frame, set background pixels to white. 38 if (diffR >td||diffG>td||diffB>td) { 39 img.pixels[i] = color(currR, currG, currB); 40 } else { 41 img.pixels[i] = color(255, 255, 255); 42 } 43 } 44 img.updatePixels(); 45 //use mouse to adjust the blur effect; 46 fastblur(img,(int)map(mouseX,0,width,1,20)); 47 //display image. 48 image(img, 0, 0); 49 } 50 51 void keyPressed() { 52 if (key == ‘ ‘) { 53 arraycopy(img.pixels, backgroundPixels); 54 } 55 }
1 void fastblur(PImage img,int radius){ 2 3 if (radius<1){ 4 return; 5 } 6 int w=img.width; 7 int h=img.height; 8 int wm=w-1; 9 int hm=h-1; 10 int wh=w*h; 11 int div=radius+radius+1; 12 int r[]=new int[wh]; 13 int g[]=new int[wh]; 14 int b[]=new int[wh]; 15 int rsum,gsum,bsum,x,y,i,p,p1,p2,yp,yi,yw; 16 int vmin[] = new int[max(w,h)]; 17 int vmax[] = new int[max(w,h)]; 18 int[] pix=img.pixels; 19 int dv[]=new int[256*div]; 20 for (i=0;i<256*div;i++){ 21 dv[i]=(i/div); 22 } 23 24 yw=yi=0; 25 26 for (y=0;y<h;y++){ 27 rsum=gsum=bsum=0; 28 for(i=-radius;i<=radius;i++){ 29 p=pix[yi+min(wm,max(i,0))]; 30 rsum+=(p & 0xff0000)>>16; 31 gsum+=(p & 0x00ff00)>>8; 32 bsum+= p & 0x0000ff; 33 } 34 for (x=0;x<w;x++){ 35 36 r[yi]=dv[rsum]; 37 g[yi]=dv[gsum]; 38 b[yi]=dv[bsum]; 39 40 if(y==0){ 41 vmin[x]=min(x+radius+1,wm); 42 vmax[x]=max(x-radius,0); 43 } 44 p1=pix[yw+vmin[x]]; 45 p2=pix[yw+vmax[x]]; 46 47 rsum+=((p1 & 0xff0000)-(p2 & 0xff0000))>>16; 48 gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; 49 bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff); 50 yi++; 51 } 52 yw+=w; 53 } 54 55 for (x=0;x<w;x++){ 56 rsum=gsum=bsum=0; 57 yp=-radius*w; 58 for(i=-radius;i<=radius;i++){ 59 yi=max(0,yp)+x; 60 rsum+=r[yi]; 61 gsum+=g[yi]; 62 bsum+=b[yi]; 63 yp+=w; 64 } 65 yi=x; 66 for (y=0;y<h;y++){ 67 pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; 68 if(x==0){ 69 vmin[y]=min(y+radius+1,hm)*w; 70 vmax[y]=max(y-radius,0)*w; 71 } 72 p1=x+vmin[y]; 73 p2=x+vmax[y]; 74 75 rsum+=r[p1]-r[p2]; 76 gsum+=g[p1]-g[p2]; 77 bsum+=b[p1]-b[p2]; 78 79 yi+=w; 80 } 81 } 82 }
代码主要分为2个部分:
1. main
获取摄像头帧video,使用PImage对象img作为缓存帧,通过空格保存对比帧background,使用阀值将对比帧与缓存帧之间相同的部分存为指定颜色(例如:白色、黑色),再显示不同的部分。
2. fastblur
简单高斯模糊,本来是想进行边缘柔化的,结果发现这种方法不行,看来只有另外找了。
Processing玩抠图
时间: 2024-10-01 07:18:22