int selected = 0; // 選択中の画像番号
// 画像用の変数
PImage[] img = new PImage[9];
// 出力ファイル名
String[] fName = {"元", "1元細線化", "2ノイズ", "2ノイズ細線化",
"2OC", "2OC細線化", "3元細線化", "3ノイズ細線化", "3OC細線化"};
int w = 400;
int h = 200;
int [] m_t = {0, 0, 0, 2, 2, 2, 1, 1, 1}; // 上マスク
int [] m_b = {1, 1, 1, 2, 2, 2, 0, 0, 0}; // 下マスク
int [] m_l = {0, 2, 1, 0, 2, 1, 0, 2, 1}; // 左マスク
int [] m_r = {1, 2, 0, 1, 2, 0, 1, 2, 0}; // 右マスク
int [] m_lt = {0, 0, 2, 0, 2, 1, 2, 1, 1}; // 左上マスク
int [] m_rt = {2, 0, 0, 1, 2, 0, 1, 1, 2}; // 右上マスク
int [] m_lb = {2, 1, 1, 0, 2, 1, 0, 0, 2}; // 左下マスク
int [] m_rb = {1, 1, 2, 1, 2, 0, 2, 0, 0}; // 右下マスク
void setup() {
size(800, 400);
noSmooth();
boolean isRightSize = true;
boolean isBW = true;
img[0] = loadImage("元.bmp");
// サイズ判定
if (img[0].width != w || img[0].height != h) {
isRightSize = false;
}
// 白黒判定
for (int j=0; j<h; j++) {
for (int i=0; i<w; i++) {
if (img[0].pixels[i+j*w]!=color(0) && img[0].pixels[i+j*w]!=color(255)) {
isBW = false;
}
}
}
if (!isRightSize || !isBW) {
println("サイズが違うか、白黒画像ではありません");
exit();
} else {
// img[0]を細線化した画像をimg[1]に保存
// img[0]にノイズを追加した画像をimg[2]に保存
// img[2]を細線化した画像をimg[3]に保存
// img[2]にオープニング→クロージングの処理を加えた画像をimg[4]に保存
// img[4]を細線化した画像をimg[5]に保存
println("完了");
textFont(createFont("MS Pゴシック", 48));
background(0);
image(img[0], 0, 0, width, height);
}
}
void draw() {
background(0);
// gif画像でなければ普通に表示
if (selected <= 5) {
image(img[selected], 0, 0, width, height);
}
// gif画像ならkeyPressedで設定した動画を表示
else {
}
fill(255, 0, 0);
text(fName[selected], 30, height-30);
fill(255);
}
// ノイズ追加
void addNoise(int n) {
// n番を元画像と同じ画像にする
img[n] = img[0].get();
// 画素数の1/100回の繰り返し
for (int i=0; i<w*h/100; i++) {
// 0~w*h-1の範囲の乱数をint rに入れる
int r = int(random(w*h));
// n番目の画像のr番目のピクセルの明度をfloat bに入れる
float b = brightness(img[n].pixels[r]);
// n番目の画像のr番目のピクセルに明度255-bの色を設定する
img[n].pixels[r] = color(255-b);
}
img[n].save("data/"+ fName[n] +".png");
}
// オープニング&クロージング
void openClose(int a, int n) {
img[n] = img[a].get();
img[n].save("data/"+ fName[n] +".png");
}
// 画像aを画像nにコピーして細線化する
void thinning(int a, int n) {
img[n] = img[a].get();
image(img[n], 0, 0, width, height);
while (true) {
int count=0;
count += cutLayer(n, 0);
count += cutLayer(n, 1);
count += cutLayer(n, 2);
count += cutLayer(n, 3);
if (count == 0) {
break;
}
}
img[n].save("data/"+ fName[n] +".png");
img[n].updatePixels();
}
// 指定された方向(dirが0~3なら左上,右下,右上,左下)から1層削る
// 削った数を戻り値として返す
int cutLayer(int n, int dir) {
PImage temp = img[n].get(); // n番の画像を仮変数tempにコピー
int dCount = 0; // 削ったピクセル数
int[][] mask = new int[3][9];
switch(dir) {
case 0: // 左上から削る場合
mask[0] = m_lt;
mask[1] = m_t;
mask[2] = m_l;
break;
case 1: // 右下から削る場合
mask[0] = m_rb;
mask[1] = m_b;
mask[2] = m_r;
break;
case 2: // 右上から削る場合
mask[0] = m_rt;
mask[1] = m_t;
mask[2] = m_r;
break;
case 3: // 左下から削る場合
mask[0] = m_lb;
mask[1] = m_b;
mask[2] = m_l;
break;
}
for (int j=1; j<h-1; j++) {
for (int i=1; i<w-1; i++) {
boolean hit = false; // マスクのどれかに一致したかどうかのフラグ
// 3種類のマスクについての繰り返し
for (int k=0; k<3; k++) {
int count = 0; // マスクとの一致数カウント
for (int l=0; l<9; l++) {
// int x にマスク内横位置(-1~1)を入れる
// int y にマスク内縦位置(-1~1)を入れる
// tempの(i+x, j+y)のピクセルの明度をbに入れる
// k番目のマスクのl番目の位置の値×255がbと一致していたらcountを増やす
}
// 6箇所がすべて一致していたらフラグをtrueにする
}
if (hit) {
// 画像nの(i, j)のピクセルを黒にする
// もともとそこが白だった場合はdCountを増やす
}
}
}
image(img[n], 0, 0, width, height);
return dCount;
}
void keyPressed() {
int k = key-'0';
if (k>=0 && k<=8) {
selected = k;
if (k >= 6) {
}
}
}