Processing玩抠图
阅读原文时间:2023年07月10日阅读:1

突然兴起想玩一下抠图,试着用自带的Example\video来改,花了一个中午做了个小样:

分别是白色为底与黑色为底的效果,代码如下:

import processing.video.*;
int numPixels;
int[] backgroundPixels;
Capture video;
PImage img;

void setup() {
size(640, 480);
video = new Capture(this, width, height);
video.start();
numPixels = video.width * video.height;
backgroundPixels = new int[numPixels];
img = new PImage(video.width, video.height);//make a copy of video.
frameRate(30);
}

void draw() {
if (video.available()) {
video.read();
}
img = video;//use img as a template
img.loadPixels();
for (int i = 0; i < numPixels; i++) { color currColor = img.pixels[i]; color bkgdColor = backgroundPixels[i]; int currR = (currColor >> 16) & 0xFF;
int currG = (currColor >> 8) & 0xFF;
int currB = currColor & 0xFF;
int bkgdR = (bkgdColor >> 16) & 0xFF;
int bkgdG = (bkgdColor >> 8) & 0xFF;
int bkgdB = bkgdColor & 0xFF;
int diffR = abs(currR - bkgdR);
int diffG = abs(currG - bkgdG);
int diffB = abs(currB - bkgdB);
int td = 20;//set threshold to 20 pixcels;

 //check each pixel of the frame, set background pixels to white.  
 if (diffR >td||diffG>td||diffB>td) {  
   img.pixels\[i\] = color(currR, currG, currB);  
 } else {  
   img.pixels\[i\] = color(255, 255, 255);  
 }  

}
img.updatePixels();
//use mouse to adjust the blur effect;
fastblur(img,(int)map(mouseX,0,width,1,20));
//display image.
image(img, 0, 0);
}

void keyPressed() {
if (key == ' ') {
arraycopy(img.pixels, backgroundPixels);
}
}

void fastblur(PImage img,int radius){

if (radius<1){
return;
}
int w=img.width;
int h=img.height;
int wm=w-1;
int hm=h-1;
int wh=w*h;
int div=radius+radius+1;
int r[]=new int[wh];
int g[]=new int[wh];
int b[]=new int[wh];
int rsum,gsum,bsum,x,y,i,p,p1,p2,yp,yi,yw;
int vmin[] = new int[max(w,h)];
int vmax[] = new int[max(w,h)];
int[] pix=img.pixels;
int dv[]=new int[256*div];
for (i=0;i<256*div;i++){
dv[i]=(i/div);
}

yw=yi=0;

for (y=0;y>16;
gsum+=(p & 0x00ff00)>>8;
bsum+= p & 0x0000ff;
}
for (x=0;x<w;x++){

   r\[yi\]=dv\[rsum\];  
   g\[yi\]=dv\[gsum\];  
   b\[yi\]=dv\[bsum\];

   if(y==0){  
     vmin\[x\]=min(x+radius+1,wm);  
     vmax\[x\]=max(x-radius,0);  
    }  
    p1=pix\[yw+vmin\[x\]\];  
    p2=pix\[yw+vmax\[x\]\];

   rsum+=((p1 & 0xff0000)-(p2 & 0xff0000))>>16;  
   gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8;  
   bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff);  
   yi++;  
 }  
 yw+=w;  

}

for (x=0;x<w;x++){
rsum=gsum=bsum=0;
yp=-radius*w;
for(i=-radius;i<=radius;i++){
yi=max(0,yp)+x;
rsum+=r[yi];
gsum+=g[yi];
bsum+=b[yi];
yp+=w;
}
yi=x;
for (y=0;y<h;y++){
pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
if(x==0){
vmin[y]=min(y+radius+1,hm)*w;
vmax[y]=max(y-radius,0)*w;
}
p1=x+vmin[y];
p2=x+vmax[y];

   rsum+=r\[p1\]-r\[p2\];  
   gsum+=g\[p1\]-g\[p2\];  
   bsum+=b\[p1\]-b\[p2\];

   yi+=w;  
 }  

}
}

代码主要分为2个部分:

1. main

获取摄像头帧video,使用PImage对象img作为缓存帧,通过空格保存对比帧background,使用阀值将对比帧与缓存帧之间相同的部分存为指定颜色(例如:白色、黑色),再显示不同的部分。

2. fastblur

简单高斯模糊,本来是想进行边缘柔化的,结果发现这种方法不行,看来只有另外找了。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器