第08回 ディザリング


今回のプログラムの最終的な機能

はじめに、これから作るプログラムが完成した時点の機能をざっと見ておく。


二値化・ポスタリゼーション


課題 1

    ベースのプログラム (このままではボタン・キーのどの組み合わせでも元画像と同じ画像がつくられるだけ)
    PImage img;       // 元画像の変数
    
    void setup() {
      size(800, 600);
      img = loadImage("1元.jpg");
      image(img, 0, 0, width, height);
    }
    
    void draw() {
    }
    
    // 二値化・ポスタリゼーション
    void decleaseColor() {
      PImage outputImg = img.get();
      if (keyPressed) {
        // outputImgにポスタリゼーション処理を行う
        outputImg.save("data/1ポスタリゼーション.png");
      } else {
        // outputImgに二値化処理を行う
        outputImg.save("data/1二値化.png");
      }
      image(outputImg, 0, 0, width, height);
    }
    
    // 組織的ディザリング
    void dither() {
      PImage outputImg = img.get();
      image(outputImg, 0, 0, width, height);
      if (keyPressed) {
        outputImg.save("data/2組織カラー.png");
      } else {
        outputImg.save("data/2組織グレー.png");
      }
    }
    
    // ランダムディザリング
    void randomDither() {
      PImage outputImg = img.get();
      image(outputImg, 0, 0, width, height);
      if (keyPressed) {
        outputImg.save("data/3ランダムカラー.png");
      } else {
        outputImg.save("data/3ランダムグレー.png");
      }
    }
    
    // 押したボタンに応じてフィルタ処理を実行
    void mousePressed() {
      if (mouseButton==LEFT) {
        decleaseColor();
      } else if (mouseButton==RIGHT) {
        dither();
      } else {
        randomDither();
      }
    }
    

  1. Processingのエディタに上のサンプルプログラムのコードをコピー&ペーストする。
  2. 「img08」という名前で保存する。
  3. 適当に画像検索してサンプル用の画像を用意する。
  4. 画像の形式に応じて以下の変更を加える。
  5. 「1元.jpg」をProcessingのウインドウにドラッグ&ドロップする。
  6. decleaseColor関数の「// outputImgに二値化処理を行う」の左に以下のコードを入れる。
  7.     outputImg.filter(THRESHOLD, 0.5);
    

  8. 実行して左クリックする。
  9. filter関数の第2引数(0.5になっている)を0~1の範囲で変えて、なるべく元画像の特徴が残るような値に調整する。
  10. 0.5で実行0.65で実行

  11. decleaseColor関数の「// outputImgにポスタリゼーション処理を行う」の左に以下のコードを入れる。
  12. outputImg.filter(POSTERIZE, 2);
    

  13. 実行し、普通に左クリックした後で、キーボードのいずれかのキーを押しながら左クリックする。
  14. ここで作る提出物
    ここで記録するもの
    ※ うまくいかないときは最終的なdecleaseColor関数とコードを見比べる。
    (赤い塗りつぶし部分は人によって異なる)

組織的ディザリング

課題 2

  1. dither関数の「PImage outputImg = img.get();」の後に以下のコード・コメント文を追加する。
  2.   // ベイヤー型ディザリングフィルタのマスク
      float[] mask = {
        0, 8, 2, 10, 
        12, 4, 14, 6, 
        3, 11, 1, 9, 
        15, 7, 13, 5
      };
      for (int j=0; j<img.height; j++) {
        for (int i=0; i<img.width; i++) {
          // (i, j)のピクセルの色をcolor cに入れる
          // マスク上の対応位置(x, y)を求める
          // マスクの値に応じた閾値との大小に応じて色成分を0か255にする
          if (keyPressed) {
          } else {
          }
        }
      }
    

  3. 「// (i, j)のピクセルの色をcolor cに入れる」の左に、対応するコードを追加する。

  4. 「// マスク上の対応位置(x, y)を求める」の下に、対応するコードを追加する。

  5. 「} else {」の下に、以下のコードを追加する。
  6.         float br = brightness(c) < mask[x+y*4]*16+8 ? 0:255;
            outputImg.pixels[i+j*img.width] = color(br);
    

  7. 実行して右クリックする。
  8. 「float br = brightness(c) < mask[x+y*4]*16+8 ? 0:255;」を、その2行上の「if (keyPressed) {」の下にコピー&ペーストする。

  9. その行を「元画像の赤の強さとマスクを比較して、結果に応じて出力画像の赤の強さを決める」ように書き換える。
  10. 同様にして緑・青に対する処理を追加する(値を入れる変数は「float g」「float b」)。

  11. その下に「r, g, bを使って作った色を、出力画像の(i, j)のピクセルの色に設定する」処理を追加する。
  12. 実行し、普通に右クリックした後で、キーボードのいずれかのキーを押しながら右クリックする。

  13. できた画像を開いてみると、8色しか使っていないのに、かなり元画像の色合いが残っているように見える。
    しかし、一部を拡大してみると4×4ピクセルのパターンが繰り返されているのがわかる。また、空のようなグラデーションのかかった部分には、疑似エッジができる。
    ここで作る提出物
    ※ うまくいかないときは最終的なdither関数とコードを見比べる。

ランダムディザリング

課題 3

  1. randomDither関数の「image(outputImg, 0, 0, width, height);」の上に、dither関数の二重ループの処理をコピー&ペーストする。

  2. エラーになっている4箇所の「mask[x+y*4]*16+8」をすべて「random(256)」に書き換える。

  3. コメント文「// マスクの値に応じた閾値との大小に応じて色成分を0か255にする」を、「// 0~255のランダムな値との大小に応じて色成分を0か255にする」に書き換える。

  4. randomDither関数から以下のコードを削除する。
  5.       // マスク上の対応位置(x, y)を求める
          int x = i%4;
          int y = j%4;
    
    この関数ではマスクは使わないので、x, yは不要。

  6. 実行して中央ボタン(ホイール)をクリックする。
  7. さらに続けてキーボードのいずれかのキーを押しながら中央ボタン(ホイール)をクリックする。



  8. 組織的ディザリングと比べると、4×4のパターンを使っていないので「繰り返し感」がなくなり、疑似エッジもなくなるが、「ザラザラ感」が目立つ画像になる。
    (離れて見るとそれなりに元画像の特徴が残っているのがわかる)
    ここで作る提出物
    ※ うまくいかないときは最終的なrandomDither関数とコードを見比べる。

提出

小テスト予告



戻る inserted by FC2 system