第14回 疑似カラー・空間フィルタリング・そのほかの処理

課題 1 (疑似カラー)

143ページの図5.20のトーンカーブを使った疑似カラー画像を作る。

    元画像のそれぞれのピクセルの明るさに応じて、出力画像の赤、緑、青成分の明るさを下のトーンカーブによって決める。


  1. 以下のプログラムのコードをコピーし、Processingのエディタに貼り付ける。
  2. PImage img;
    img = loadImage("1元.jpg"); // 画像を読み込む
    img.filter(GRAY); // グレースケール化
    // 疑似カラー化
    float r, g, b;
    for (int i=0;i<img.pixels.length;i++){
      float br=brightness(img.pixels[i])/255.0; // i番目のピクセルの明度を取得して0~1に規格化
      if (br<0.25){ // 0~0.25の明るさ
        r=0; g=br*4; b=1;
      }else if(br<0.5){// 0.25~0.5の明るさ
        r=0; g=1; b=(0.5-br)*4;
      }else if(br<0.75){// 0.5~0.75の明るさ
        r=(br-0.5)*4; g=1; b=0;
      }else{// 3/4~1の明るさ
        r=1; g=(1-br)*4; b=0;
      }
      img.pixels[i] = color(r*255, g*255, b*255);
    }
    img.save("data/1疑似カラー.jpg"); // ファイルに保存
    
  3. 「ex14」という名前で保存する。
  4. 適当に画像検索して変換に使う画像(デジカメで撮った写真のようなもの。明るい部分、暗い部分、中間の明るさの部分を含むもの)を用意する。
  5. 画像の形式に応じて以下の変更を加える。
  6. 1元.jpgをProcessingのエディタにドラッグ&ドロップする。
  7. プログラムを実行する。
  8. プログラムのdataフォルダーを開く(メニューの「スケッチ」→「スケッチフォルダーを開く」)。
  9. そのフォルダーにできた「1疑似カラー.jpg」を開き、「暗いところは青、明るいところは赤、中間の明るさのところが緑」になっていることを確認する。
  10. 1元.jpg1疑似カラー.jpg


    ここで作る提出物

課題 2 (平滑化)

Processingのライブラリ機能を使って、画像を平滑化する。

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img;
    img = loadImage("2元.jpg"); // 画像を読み込む
    img.filter(BLUR, 5); // 画像をぼかす
    img.save("data/2平滑化.jpg"); // ファイルに保存
    
  3. 適当に画像検索して変換に使う画像(デジカメで撮った写真のようなもの。ノイズが乗ったような、ザラザラした部分があるもの)を用意する。
  4. 画像の形式に応じて以下の変更を加える。
  5. 2元.jpgをProcessingのエディタにドラッグ&ドロップする。
  6. プログラムを実行する。
  7. dataフォルダーにできた「2平滑化.jpg」と「2元.jpg」を見比べて、「2平滑化.jpg」の方がぼやけた状態になっていることを確認する。
  8. 2元.jpg2平滑化.jpg


    ここで作る提出物

    ※ このアルゴリズムでは、ある位置のピクセルの色を、(元画像の)それを囲む正方形の色を平均して決める。プログラムの「img.filter(BLUR, 5);」の「5」のところに入れる数値によってその正方形の大きさが変わる。これを大きくするほどぼやけ方が強くなる。

課題 3 (エッジ抽出)

テキストの図5.32, 5.35のフィルタを使い、画像からエッジを取り出す。

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img;
    img = loadImage("3元.jpg"); // 画像を読み込む
    img.filter(GRAY); // グレースケールにする
    float[] outX = new float[img.width*img.height]; // 横の明度差を入れる配列
    float[] outY = new float[img.width*img.height]; // 縦の明度差を入れる配列
    for(int j=0;j<img.height;j++){
      for(int i=0;i<img.width;i++){
        int pos=i+j*img.width;
        if (i<img.width-1) outX[pos]=brightness(img.pixels[pos+1])-brightness(img.pixels[pos]); // 横に並んだピクセルの明度の差
        if (j>0) outY[pos]=brightness(img.pixels[pos-img.width])-brightness(img.pixels[pos]); // 縦に並んだピクセルの明度の差
      }
    }
    // 縦横の明度差の2乗の平方根を明度とした画像を作る
    for (int i=0;i<img.pixels.length;i++){
      img.pixels[i]=color(sqrt(outX[i]*outX[i]+outY[i]*outY[i]));
    }
    img.save("data/3エッジ.jpg"); // ファイルに保存
    
  3. 適当に画像検索して変換に使う画像(デジカメで撮った写真のようなもの。建物など、輪郭がはっきりした部分があるもの)を用意する。
  4. 画像の形式に応じて以下の変更を加える。
  5. 3元.jpgをProcessingのエディタにドラッグ&ドロップする。
  6. プログラムを実行する。
  7. dataフォルダーにできた「3エッジ.jpg」を開き、輪郭線が白で抽出されていることを確認する。
  8. 3元.jpg3エッジ.jpg


    ここで作る提出物

    ※ このプログラムでは、149ページの(5.6)式の「勾配」を計算し、それを明るさとして使っている。そのおかげで縦、横、斜めの線すべてがきれいに取り出せる。

課題 4 (ハーフトーニング)

テキスト156ページの図5.50のディザパターン(Bayer型)を使い、ハーフトーニングした画像を作る。

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img;
    int[] bayer={0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5};
    img = loadImage("4元.jpg"); // 画像を読み込む
    img.filter(GRAY); // グレースケールにする
    for(int j=0;j<img.height;j+=4){
      for(int i=0;i<img.width;i+=4){
        for (int k=0;k<16;k++){
          int ci=i+k%4; // チェック位置(横)
          int cj=j+k/4; // チェック位置(縦)
          if (ci>=img.width || cj>=img.height) continue; // チェック位置が画像範囲外なら処理をスキップ
          if (brightness(img.pixels[ci+cj*img.width])>=bayer[k]*16+8){
            img.pixels[ci+cj*img.width]=color(255);
          }else{
            img.pixels[ci+cj*img.width]=color(0);
          }
        }
      }
    }
    img.save("data/4ディザ.jpg"); // ファイルに保存
    
  3. 適当に画像検索して変換に使う画像(デジカメで撮った写真のようなもの。明るい部分、暗い部分、中間の明るさの部分を含むもの。課題1の元画像を使いまわしてもよい。)を用意する。
  4. 画像の形式に応じて以下の変更を加える。
  5. 4元.jpgをProcessingのエディタにドラッグ&ドロップする。
  6. プログラムを実行する。
  7. dataフォルダーにできた「4ディザ.jpg」を開き、白黒の点の集まりでできていることを確認する。
  8. 4元.jpg4ディザ.jpg


    ここで作る提出物

    ※ 暗いところは黒い点の密度、明るいところは白い点の密度が高くなるので、白黒の点しか使っていないのに離れて見るとグレースケールのように見える。

課題 5 (アルファブレンディング)

テキスト157ページの(5.9)式の重み付けを使い、2つの画像を合成する。

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img1, img2;
    float alpha=0.5; // 重み
    img1 = loadImage("5元1.jpg"); // 画像を読み込む
    img2 = loadImage("5元2.jpg"); // 画像を読み込む
    for(int i=0;i<img1.pixels.length;i++){
      float r=alpha*red(img1.pixels[i])+(1-alpha)*red(img2.pixels[i]);
      float g=alpha*green(img1.pixels[i])+(1-alpha)*green(img2.pixels[i]);
      float b=alpha*blue(img1.pixels[i])+(1-alpha)*blue(img2.pixels[i]);
      img1.pixels[i]=color(r,g,b);
    }
    img1.save("data/5合成.jpg"); // ファイルに保存
    
  3. 適当に画像検索して合成に使う画像を用意する。ただし、2枚の画像のサイズが同じになるようにする
  4. 画像の形式に応じて以下の変更を加える。
  5. 2枚の画像をProcessingのエディタにドラッグ&ドロップする。
  6. プログラムを実行する。
  7. dataフォルダーにできた「5合成.jpg」を開き、元画像が合成されたものになっていることを確認する。
  8. 5元1.jpg5元2.jpg5合成.jpg


    ここで作る提出物

    ※ 2行目の「alpha」に入れる値を0~1の範囲で変えると、片方の影響が強くなる(大きくすると「5元1.jpg」の方が強く出るようになる)。

課題 6 (エンボス)

テキスト159ページの(5.10)式を使い、レリーフのような画像を作る。

  1. Processingのエディタのコードを消し、以下のコードをコピー&ペーストする。
  2. PImage img;
    int d=2; // ずらし幅
    img = loadImage("6元.jpg"); // 画像を読み込む
    img.filter(GRAY);
    PImage imgOut = createImage(img.width-d, img.height-d, RGB); // 出力画像
    for (int j=0;j<img.height-d;j++){
      for (int i=0;i<img.width-d;i++){
        float f1=brightness(img.pixels[i+d+(j+d)*img.width]); // 元画像の(i+d, j+d)の位置の明度
        float f2=255-brightness(img.pixels[i+j*img.width]); // 元画像の(i, j)の位置の明度を反転した値
        imgOut.pixels[i+j*imgOut.width]=color(f1+f2-128);
      }
    }
    imgOut.save("data/6エンボス.jpg"); // ファイルに保存
    
  3. 適当に画像検索して変換に使う画像(デジカメで撮った写真のようなもの)を用意する。
  4. 画像の形式に応じて以下の変更を加える。
  5. 6元.jpgをProcessingのエディタにドラッグ&ドロップする。
  6. プログラムを実行する。
  7. dataフォルダーにできた「6エンボス.jpg」を開き、「元画像の明るい部分が盛り上がっていて、左上から光が当たった浮き彫りのような画像」になっていることを確認する。
  8. 6元.jpg6エンボス.jpg


    ここで作る提出物

    ※ 2行目のdの値を変えると「浮き彫りの厚さ」が変わる。
    ※ 画像を斜めにずらして合成しているので、ずらし幅分だけ画像の縦横のサイズは小さくなる。

提出

戻る inserted by FC2 system