第15回 収縮・膨張処理、距離、細線化

課題 1 (ピクセル間の距離)

  1. 以下のプログラムのコードをコピーし、Processingのエディタに貼り付ける。
  2. int d = 20;
    void setup(){
      size(201, 301);
    }
    
    void draw(){
      // 描画範囲
      int w = width;
      int h = height-d*4;
      // グリッド
      background(255);
      stroke(0);
      for (int j=0;j<h; j+=d){
        line(0, j, w, j);
      }
      for (int i=0; i<w; i+=d){
        line(i, 0, i, h);
      }
      // 情報エリア
      fill(0);
      rect(0, h, w, d*4);
      // 座標
      int x = mouseX/d;
      int y = mouseY/d;
      // カーソル位置が範囲外なら補正
      if (x<0) x=0;
      if (x>w/d-1) x=w/d-1;
      if (y<0) y=0;
      if (y>h/d-1) y=h/d-1;
      fill(255);
      text("ユークリッド距離", 10, h+d);
      text(""+dist(0, 0, x, y), 130, h+d);
      text("市街地距離", 10, h+d*2);
      text(""+(x+y), 130, h+d*2);
      text("チェス盤距離", 10, h+d*3);
      text(""+max(x, y), 130, h+d*3);
      // スタート・ゴールのピクセルの描画
      fill(0, 0, 255);
      rect(0, 0, d, d);
      rect(x*d, y*d, d, d);
      // ピクセル中心を結ぶ線分
      line(d/2, d/2, x*d+d/2, y*d+d/2);
    }
    
    void mousePressed(){
      save("data/1距離.png");
    }
    
  3. 「ex15」という名前で保存する。
  4. プログラムを実行する。
  5. 実行画面上でカーソルを動かすと青い正方形がそれに合わせて動く(片方は左上から動かない)こと、画面下の数値がそれに応じて変わることを確認する。
  6. 適当に選んだ位置でクリックする。
  7. プログラムのdataフォルダーを開く(メニューの「スケッチ」→「スケッチフォルダーを開く」)。
  8. そのフォルダーにできた「1距離.png」を開き、クリック時の実行画面と同じになっていることを確認する。


  9. ここで作る提出物

課題 2 (ノイズ入りの文字画像の準備)

GIMPの「ノイズ」機能を使い、かすれた文字画像を作る。

  1. ペイントを起動する(Windowsボタン」→「Windowsアクセサリ」→「ペイント」)。
  2. 画像のサイズを600×400にする。


  3. 「テキスト」のアイコンをクリックし、文字サイズ36、太字の設定にして適当な文字を入れ、点線の外側でクリックする。


  4. 「選択」をクリックしてから、画像で右クリックして「色の反転」を選択する (白黒が反対になる)。


  5. 「2元.png」という名前をつけて、今日のプログラムのdataフォルダに保存する。
  6.   拡大表示してみると、文字の周辺部には白でも黒でもないピクセルがある。これは、「アンチエイリアス」という滑らかに見せるテクニックによるものだが、このままでは今日の課題5, 6の「細線化」がうまくできない。そこで、以下のようにしてすべてのピクセルを「白か黒」にする。


  7. ペイントを終了させる。
  8. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  9. PImage img = loadImage("2元.png");
    img.filter(THRESHOLD, 0.5);
    img.save("data/2元.png");
    
  10. プログラムを実行する。
  11. dataフォルダの「2元.png」を開いて拡大表示し、黒と白以外のピクセルがなくなっていることを確認する。


  12. GIMPを起動する (Windowsボタン→「GIMP 2.10.8」)。
  13. 「2元.png」をGIMPの画面にドラッグ&ドロップする。
  14. 「Filters」→「Noise」→「Spread」を選択し、表示されるウインドウでそのままOKボタンをクリックする。すると、下の図のようににじんだ状態になる。
  15. この処理では、白と黒のピクセルがランダムに置き換えられる。


  16. 「ファイル」→「名前をつけてエクスポート」で「2ノイズ.png」という名前で画像をdataフォルダに出力する。
  17. GIMPを終了させる。


  18. ここで作る提出物

課題 3 (収縮・膨張)

文字画像に「収縮」「膨張」の処理を行い、画像がどう変化するかを調べる。

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img = loadImage("2ノイズ.png"); // ノイズのある画像を読み込む
    img.filter(ERODE); // 収縮処理
    img.save("data/3収縮.png"); // ファイル出力
    img = loadImage("2ノイズ.png"); // ノイズのある画像を読み込む
    img.filter(DILATE); // 膨張処理
    img.save("data/3膨張.png"); // ファイル出力
    


  3. プログラムを実行する。
  4. dataフォルダの「3収縮.png」「3膨張.png」を開いて、上の説明のような状態になっていることを確認する。


  5. ここで作る提出物

課題 4 (オープニング・クロージング)

収縮・膨張を組み合わせると、文字部分の太さをあまり変えずにノイズを消すことができる。

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img = loadImage("2ノイズ.png"); // ノイズのある画像を読み込む
    img.filter(ERODE); // 収縮処理
    img.filter(DILATE); // 膨張処理
    img.save("data/4オープニング.png"); // ファイル出力
    img = loadImage("2ノイズ.png"); // ノイズのある画像を読み込む
    img.filter(DILATE); // 膨張処理
    img.filter(ERODE); // 収縮処理
    img.save("data/4クロージング.png"); // ファイル出力
    
  3. プログラムを実行する。
  4. dataフォルダの「4オープニング.png」「4クロージング.png」を開いて、上の説明のような状態になっていることを確認する。


  5. ここで作る提出物

課題 5 (細線化)

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img;
    int [][] wp ={{0, 1, 3}, {0, 1, 2}, {1, 2, 5}, {0, 3, 6}, {}, {2, 5, 8}, {3, 6, 7}, {6, 7, 8}, {5, 7, 8}};
    int [][] fType = {{0, 3, 1}, {8, 5, 7}, {2, 1, 5}, {6, 3, 7}};
    
    void setup() {
      img = loadImage("2元.png"); // 画像読み込み
      while (true) {
        if (thining()==0) {
          break;
        }
      }
      img.save("data/5細線化(元).png"); // 画像出力
    }
    
    int thining() {
      int w = img.width;
      int h = img.height;
      int count = 0;
    
      for (int m=0; m<4; m++) {
        PImage img2 = img.get(0, 0, w, h);
        for (int j=1; j<h-1; j++) {
          for (int i=1; i<w-1; i++) {
            for (int l=0; l<fType[m].length; l++) {
              if (
                brightness(img.pixels[i+wp[fType[m][l]][0]%3-1 + (j+wp[fType[m][l]][0]/3-1)*w]) == 0 &&
                brightness(img.pixels[i+wp[fType[m][l]][1]%3-1 + (j+wp[fType[m][l]][1]/3-1)*w]) == 0 &&
                brightness(img.pixels[i+wp[fType[m][l]][2]%3-1 + (j+wp[fType[m][l]][2]/3-1)*w]) == 0 &&
                brightness(img.pixels[i+wp[8-fType[m][l]][0]%3-1 + (j+wp[8-fType[m][l]][0]/3-1)*w]) == 255 &&
                brightness(img.pixels[i+wp[8-fType[m][l]][1]%3-1 + (j+wp[8-fType[m][l]][1]/3-1)*w]) == 255 &&
                brightness(img.pixels[i+wp[8-fType[m][l]][2]%3-1 + (j+wp[8-fType[m][l]][2]/3-1)*w]) == 255
                ) {
                if (brightness(img2.pixels[i+j*w])==255) {
                  count++;
                }
                img2.pixels[i+j*w] = color(0);
              }
            }
          }
        }
        img = img2.get(0, 0, w, h);
      }
      return count;
    }
    
  3. プログラムを実行する。
  4. dataフォルダの「5細線化(元).png」を開いて、文字の芯が取り出されていることを確認する。
  5. プログラムのファイル名の部分を以下のように書き換える。
  6. プログラムを実行する。
  7. dataフォルダの「5細線化(ノイズ).png」を開いて、上の説明のような状態になっていることを確認する。


  8. ここで作る提出物

課題 6 (オープニング・クロージングした画像の細線化)

細線化の前処理としてオープニングやクロージングを行うと、ノイズの影響を減らすことができる。

  1. プログラムを以下のように書き換える。
  2. プログラムを実行する。
  3. dataフォルダの「6細線化(オープニング).png」を開いて、上の説明のような状態になっていることを確認する。
  4. プログラムを以下のように書き換える。
  5. プログラムを実行する。
  6. dataフォルダの「6細線化(クロージング).png」を開いて、上の説明のような状態になっていることを確認する。


  7. ここで作る提出物

提出

戻る inserted by FC2 system inserted by FC2 system