Image Guid

画像解析を行うために必要な基礎知識です。

前田稔(Maeda Minoru)の超初心者のプログラム入門

Image(画像)概要

  1. コンピュータで扱う画像は、ピクセル(画素)を格子状に並べて表現されます。
    ページ先頭の画像は、一部を切り取って拡大した「横:575×縦:418」ピクセルの画像です。
    最近ではデジタルカメラが普及し、簡単に画像ファイルを作成することが出来ます。
    ピクセルの数によって画質が決まり、1996年に発売された伝説の名機「QV-10」は320×240ドット(ピクセル)でした。
    数年前に購入したデジカメは1600×1200ピクセルで、最近購入したスマホは3264×1836ピクセルです。
    画像を拡大するとピクセルが見えてきますが、画素の数が多いほど拡大に耐えられます。
  2. 画像ファイルの形式は BMP, JPG, GIF, PING, DDS など様々なファイル形式が使われています。
    ファイル形式のいかんに関わらず、ピクセル(画素)が格子状に並んでいます。
  3. ピクセル(ドット)の記録形式も様々ですが、最も一般的な方法は RGB を8ビットずつ(1ピクセル=24ビット)で記録する方法です。
    この記録形式は「24ビットBMP形式」などと呼ばれていて、これから説明するプログラムもこの形式の画像を扱います。
    色の3原色(赤緑青)を8ビット(256階調)の組み合わせで表します。
    青色(B)の8ビット 緑色(G)の8ビット 赤色(R)の8ビット
  4. 画像の解析は、RGB の24ビットに立ち返って赤緑青のピクセル単位に処理するのが基本です。
    HBITMAP に直接アクセスできたら良いのですが、プロテクトされているようです。
    このコーナーでは使いませんが GetDIBits() 関数を使えばピクセルデータを取得することが出来ます。
    GetDIBits() の例は、画像を BMP File で保存などを参照して下さい。
        HBITMAP     hBmp;   //画像の HBITMAP
    
  5. HBITMAP に直接アクセス出来ないので Win32 API のデバイス独立ビットマップ(DIB)を使ってピクセルデータに直接アクセスします。
    DIB(Device-Independent Bitmap) は CreateDIBSection() を使って生成して、今回は DibStruct; 構造体を使って管理します。
    HBITMAP hBmp が HBITMAP 画像の領域で、hBmpDC が DIB のハンドルです。
    LPBYTE Data が 24bit ピクセルデータへのポインターです。
    ポインターを通じてピクセルデータを修正すると直ちに描画する画像に反映します。
    BMP FILE(DIB も同じ)ではファイルの先頭に格納されているのは最下段の行で、上下逆に格納されています。
    typedef struct
    {   HBITMAP         hBmp;
        HDC             hBmpDC;
        LPBYTE          Data;           // 24bit DIB の BITMAP DATA
    }   DibStruct;
    
  6. LPBYTE Data(ピクセルデータへのポインター)を #define を使って三次元配列のように参照します。
    MAP(y,x,c) を使って、例えば次のようにピクセルデータにアクセスします。
    Show(Dib.hBmpDC, 0, 0); で、入力した BMP 画像をデバイス独立ビットマップ(DIB)に転送します。
    wk= MAP(dy, dx, cp); で「行:dy, 列:dx, 色:cp」の値を wk に取得しています。
    #define     MAP(y,x,c)  (Dib.Data[(y*m_Width+x)*3+c])
    
        DibStruct   Dib;                //RGB 画像解析の構造体
    
        WORD    wk;
        Show(Dib.hBmpDC, 0, 0);
        for (dy = 0; dy<m_Height; dy++)
            for (dx = 0; dx<m_Width; dx++)
                for (cp = 0; cp<3; cp++)
                {
                    wk= MAP(dy, dx, cp);
    
                        ・
                        ・
                        ・
    
  7. 超初心者のC言語(Windows) の掲載を始めた頃は int 型は16ビットサイン付きで、表現できる範囲は 32767~-32768 でした。
    これでは用途によってオーバーフローが起こるので LONG(32ビット) がしばしば使われていました。
    現在では int 型が 32ビットになり LONG を使う必要は無くなってきています。
    私のプログラムで LONG 型が使われているのは、昔のプログラムの名残です。
    C#でも画像解析を行うプログラムを掲載することにしました。
    C#の画像解析は Image Guid から参照して下さい。

[Next Chapter ↓] Image 3原色

超初心者のプログラム入門(Win32API C++)