簡単にできる画像処理プログラミング   ('02年07月24日初版) '02.08.07更新


 GLIBW32 ver 1.33 では、次の3つの関数が追加されました。
  1. ビットマップを読み込むグローバル関数:loadbmp()
  2. 座標値の色を読み出すメンバ関数: GRAPH::getpixel()
  3. 点を打つメンバ関数のフルカラー版: GRAPH::pset()
これらを使えば、画像処理プログラムが書けます。  ここでは、サンプル・プログラムを使って簡単な画像処理を行います。サンプルで使用 している画像ファイル loadbmp.bmp (272KB) が入用な方はこちらからダウンロードして お使いください。  以下では、写真画像を一旦ウィンドウに読み込み、ピクセル(画素)を走査し、画像 の色データを取得して画像処理を行います。  ビットマップ・ファイルをグラフィック・ウインドウに読み込むには、グローバル関 数 loadbmp() を呼び出します。    loadbmp("loadbmp.bmp"); あるいは、ファイルが見つからないなどの原因で読み込みに失敗した場合のエラー処理 を含めて    if( loadbmp("loadbmp.bmp") ){     gend();     exit(1);    } などとします。 ただし、表示される範囲は現在のビューポート内に限られますので、あらかじめ画像 ファイルの幅と高さのサイズを調べておくとよいでしょう。  例えば、Windows付属の"ペイント"でBMPファイルを開いてメニューの    [変形] --> [キャンバスの色とサイズ] で画像の幅と高さを知ることができます(単位をピクセルにすること)。

ロードした画像をマッピングする  最初の例は、読み込んだ画像(左側)のピクセルをスキャンし、各ピクセルのRGB値 を読み取ってそのまま右側にマッピングするプログラムです。
ロードした画像をマップする ソースファイル(loadbmp02.cpp)  プログラムを示します。

// loadbmp02.cpp
// グラフィックのマッピング
#include "glibw32.h"

const int Xsize = 320, Ysize = 290; // ビットマップのサイズ   

int main()
{
    ginit( 2*Xsize, Ysize );  // ウィンドウはビットマップ2つ分のサイズ
    loadbmp( "loadbmp.bmp" ); // ビットマップのロード

    GRAPH g1,g2;
    g1.window( 0, 0, Xsize-1, Ysize-1 ); // ロードした画像の座標系を設定    
    g1.view( 0, 0, Xsize -1, Ysize-1 );
    g2.window( 0, 0, Xsize-1, Ysize-1 ); // マッピングを行う座標系を設定    
    g2.view( Xsize, 0, 2*Xsize-1, Ysize-1 );

    // g1のピクセルをスキャンして、g2にマッピング
    int rgb[3]; // RGB値
    for(int i = 0; i < Xsize; i++)
        for(int j = 0; j < Ysize; j++)
            if( g1.getpixel(i, j, rgb) ) g2.pset(i, j, rgb);

    gend();

    return 0;
}
 GRAPHクラスのオブジェクト g1 を読み込んだ画像の範囲に座標設定し、g2 はマッ
ピングする範囲に設定します。
 色のRGB値をint型の配列rgb[3](rgb[0]は赤、rgb[1]は緑、rgb[2]は青)で扱い、
ピクセル(画素)の色を読み出すメンバー関数 GRAPH::getpixel()を次のように呼び
出せば、

      g1.getpixel(i, j, rgb);

オブジェクトg1の座標点(i,j)のRGB値を配列rgb[3]に上書きして返します。

 次にRGB値rgb[3]の色で点を打つには、メンバー関数 GRAPH::pset()を使います。

      g2.pset(i, j, rgb);

この関数は、オブジェクトg2の座標点(i,j)にRGB値rgb[3]の色で点を打ちます。
これらの関数は、RGB値を直接使うため任意の色が扱えます。


ネガに変換  次の例は、色を変換してマッピングします。写真のネガのようにするには、RGB値 の各値を最大値の255から引いた値にすると色が反転します。
ネガ ソースファイル(loadbmp03.cpp) コードは次のようになります。

    // g1のピクセルをスキャンして、g2にマッピング
    int rgb[3]; // RGB値
    for(int i = 0; i < Xsize; i++)
        for(int j = 0; j < Ysize; j++)
            if( g1.getpixel(i, j, rgb) ){// ピクセルの色を読み出す    
                rgb[0] = 255 - rgb[0];    //反転                             
                rgb[1] = 255 - rgb[1];    //反転
                rgb[2] = 255 - rgb[2];    //反転
                g2.pset(i, j, rgb);
            }


白黒画像に変換  白黒写真に変換するには、色の明るさをとりだします。
白黒 ソースファイル(loadbmp04.cpp)  RGB値を次のような重み付き平均値で、各階調を表します。

          int r,g,b,gray;
          r = rgb[0]; g = rgb[1]; b = rgb[2];
          gray = (77*r+151*g+28*b)/256; // 重み付きの平均値        
          rgb[0] = rgb[1] = rgb[2] = gray;

 この重み付きの平均値 gray は輝度と呼ばれるもので、カラーテレビの信号処理
に使われます。輝度は色の明るさを表します。
 重みを付けて平均を取るのは、人の視覚は赤・緑・青に対してそれぞれ感度が異
なるためで、

    青 < 赤 < 緑

の順に感度が高くなります。最も感度の高い色に重みを持たせています。


トーラス  サンプルプログラム eye07.cpp のフルカラー版です。より自然に見えます。 勿論、eye07.cpp で色の変化を青〜水色にするのではなく、黒〜水色にすれば このプログラムと同じ結果が得られます。
トーラス ソースファイル(eye10.cpp)  フルカラー版 GRAPH::pset() を使って、トーラス上の法線ベクトルと視点ベクトル とのなす角度から明るさを計算して表現します。

| 戻る |
 

Copyright(c) 2002 Yamada, K