アプリ開発で画像処理が必要になりそうなので
久しぶりになんか作ってみる。
動画でやってみる。
1. pointllize

proce55ingって、ほんとに便利ですね。
import processing.video.*;
Capture cap;
int pointillize = 16;
void setup()
{
size(480, 320);
background(0);
cap = new Capture(this, width, height, 30);
}
void captureEvent(Capture cap) {
cap.read();
}
void draw() {
image(filter(), 0, 0);
}
PGraphics filter()
{
loadPixels();
cap.loadPixels();
PGraphics pg = createGraphics(width, height, P3D);
pg.beginDraw();
pg.noStroke();
for(int x=0; x<cap.width; x+=pointillize){
for(int y=0; y<cap.height; y+=pointillize){
int loc = x + y*cap.width;
float r = red(cap.pixels[loc]);
float g = green(cap.pixels[loc]);
float b = blue(cap.pixels[loc]);
pg.fill(r,g,b,255);
pg.ellipse(x,y,pointillize,pointillize);
//pg.rect(x,y,pointillize,pointillize);
}
}
pg.endDraw();
return pg;
}
2. pointllize2

// filter関数以外は全て(1)と同じ
// ... 省略
PGraphics filter()
{
loadPixels();
cap.loadPixels();
PGraphics pg = createGraphics(width, height, P3D);
pg.beginDraw();
pg.noStroke();
for(int i=0; i<100; i++){
int x = int(random(cap.width));
int y = int(random(cap.height));
int loc = x + y*cap.width;
float r = red(cap.pixels[loc]);
float g = green(cap.pixels[loc]);
float b = blue(cap.pixels[loc]);
pg.fill(r,g,b,255);
pg.ellipse(x,y,pointillize,pointillize);
}
pg.endDraw();
return pg;
}
3. アウトライン化

// filter関数以外は全て(1)と同じ
// ... 省略
PGraphics filter()
{
loadPixels();
cap.loadPixels();
PGraphics pg = createGraphics(width, height, P3D);
pg.beginDraw();
pg.noStroke();
for(int x=0; x < width; x++){
for(int y=0; y < height; y++){
int loc = x + y * width;
color pix = cap.pixels[loc];
try{
int leftLoc = (x-1) + y * width;
color leftPix = cap.pixels[leftLoc];
//float diff = abs(brightness(pix) - brightness(leftPix)) * 2;
float r = abs(red(pix) - red(leftPix)) * 2;
float g = abs(green(pix) - green(leftPix)) * 2;
float b = abs(blue(pix) - blue(leftPix)) * 2;
pg.pixels[loc] = color(r, g, b);
pg.pixels[loc+1] = color(r, g, b);
pg.pixels[loc-1] = color(r, g, b);
}
catch(Exception e){}
}
}
pg.endDraw();
return pg;
}
4. 2階調化

// filter関数以外は全て(1)と同じ
// ... 省略
PGraphics filter()
{
int threshold = 100;
loadPixels();
cap.loadPixels();
PGraphics pg = createGraphics(width, height, P3D);
pg.beginDraw();
pg.noStroke();
for(int x=0; x < width; x++){
for(int y=0; y < height; y++){
int loc = x + y * width;
if (brightness(cap.pixels[loc]) > threshold) {
pg.pixels[loc] = color(255); // White
}
else {
pg.pixels[loc] = color(0); // Black
}
}
}
pg.endDraw();
return pg;
}
5. 移動平均法で平滑化

// smoothing operator
float[][] op = {
{0.04, 0.04, 0.04, 0.04, 0.04}
, {0.04, 0.04, 0.04, 0.04, 0.04}
, {0.04, 0.04, 0.04, 0.04, 0.04}
, {0.04, 0.04, 0.04, 0.04, 0.04}
, {0.04, 0.04, 0.04, 0.04, 0.04}
};
int op_size = 5; // 5x5 matrix
/*
float[][] op = {
{-1, -1, -1}
, {-1, 9, -1}
, {-1, -1, -1}
};
int op_size = 3; // 3x3 matrix
*/
import processing.video.*;
Capture cap;
void setup()
{
size(480, 320);
background(0);
cap = new Capture(this, width, height, 30);
}
void captureEvent(Capture cap) {
cap.read();
}
void draw() {
image(filter(), 0, 0);
}
PGraphics filter()
{
loadPixels();
cap.loadPixels();
PGraphics pg = createGraphics(width, height, P3D);
pg.beginDraw();
pg.noStroke();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++ ) {
color c = convolution(x, y);
int loc = x + y*cap.width;
pg.pixels[loc] = c;
}
}
pg.endDraw();
return pg;
}
color convolution(int x, int y)
{
float r = 0.0f;
float g = 0.0f;
float b = 0.0f;
int offset = op_size / 2;
for(int row=0; row<op_size; row++){
for(int col=0; col < op_size; col++){
int xloc = x+col-offset;
int yloc = y+row-offset;
int loc = xloc + cap.width*yloc;
loc = constrain(loc,0,cap.pixels.length-1);
r += (red(cap.pixels[loc]) * op[row][col]);
g += (green(cap.pixels[loc]) * op[row][col]);
b += (blue(cap.pixels[loc]) * op[row][col]);
}
}
return color(r, g, b);
}