ビットマップ画像の画像処理2

「ビットマップ画像の画像処理」のプログラムをより、画像処理に特化できるように改良した例です。処理後の画像も[保存]ボタンにより保存することができるようになりました。

以下のソース部分を変更すればウィンドウ内のメニューが自動的に追加され、処理を選択することができます。

メニューの設定(winbip.cpp)
//-----------------------------------------------------------------
// メニューへの追加内容
//-----------------------------------------------------------------
MenuInfo MI[] = {
    {"濃淡化",toGray}, → "メニューへの追加文字",処理関数
    {"2値化",toBin},
    {"3値化",toTriple},
    {"色反転",revColor},
    {NULL,NULL}
};

元画像   処理後の画像
(最大尤度しきい値選定法による2値化)
 

実行ファイルのダウンロード: winbip.exe

コンパイルオプション(一括ダウンロードの中にMakefileの例があります。そちらでのコンパイルをお勧めします。):
 Gami[84]% gcc -o winbip winbip.cpp wingui.cpp opthmdthr.cpp -lgdi32 -lcomctl32 -lcomdlg32 -mwindows -e_mainCRTStartup

 ダウンロード

ビットマップ画像の画像処理(winbip.cpp)
//-----------------------------------------------------------------
// winbip.cpp:
//       BMPの画像処理
//                 Last Update: <2004/12/01 08:25:11 A.Murakami>
//-----------------------------------------------------------------
#include <stdio.h>
#include <windows.h>
#include "wingui.h"
#include "opthmdthr.h" // 2値化: 最大尤度しきい値選定法
extern UINT iHeight,iWidth,iLength; // 画像: 高さ,幅,1ラインの長さ
extern LPBYTE lpOrgBMP,lpBMP;       // オリジナル画像, 表示画像
//-----------------------------------------------------------------
void toGray();         // グレースケールへの変換
void toBin();          // 2値画像への変換
void toTriple();       // 3値画像への変換
void revColor();       // 色の反転
//-----------------------------------------------------------------
// メニューへの追加内容
//-----------------------------------------------------------------
MenuInfo MI[] = {
    {"濃淡化",toGray},
    {"2値化",toBin},
    {"3値化",toTriple},
    {"色反転",revColor},
    {NULL,NULL}
};
//-----------------------------------------------------------------
// グレースケールへの変換
//-----------------------------------------------------------------
void toGray()
{
    BYTE r,g,b,gray;
    for(int i=0;i<iHeight;i++) for(int j=0;j<iWidth;j++) {
        b=lpOrgBMP[j*3+i*iLength];
        g=lpOrgBMP[j*3+i*iLength+1];
        r=lpOrgBMP[j*3+i*iLength+2];
        gray=(BYTE)(r*0.299+g*0.587+b*0.144);
        FillMemory(lpBMP+j*3+i*iLength,3,gray);
    }
}
//-----------------------------------------------------------------
// 2値化
//-----------------------------------------------------------------
void toBin()
{
    BYTE r,g,b,gray;
    BYTE iWH=255,iBW=0;
    int isize,hist[256],thr[10];
    FillMemory(hist,sizeof(int)*256,0);
    // ヒストグラムの作成[濃淡化]
    for(int i=0;i<iHeight;i++) for(int j=0;j<iWidth;j++) {
        b=lpOrgBMP[j*3+i*iLength];
        g=lpOrgBMP[j*3+i*iLength+1];
        r=lpOrgBMP[j*3+i*iLength+2];
        gray=(BYTE)(r*0.299+g*0.587+b*0.144);
        FillMemory(lpBMP+j*3+i*iLength,3,gray);
        hist[gray]++;
    }
    // [2..]値化最適しきい値の計算
    isize = iWidth*iHeight;
    calc_opthmdthr(2,256,isize,hist,thr);
    // 2値画像の作成
    for(int i=0;i<iHeight;i++) for(int j=0;j<iWidth;j++) {
        gray=lpBMP[j*3+i*iLength];
        if(gray>thr[1]){
            FillMemory(lpBMP+j*3+i*iLength,3,iWH);
        } else {
            FillMemory(lpBMP+j*3+i*iLength,3,iBW);
        }
        hist[gray]++;
    }
}
//-----------------------------------------------------------------
// 3値化
//-----------------------------------------------------------------
void toTriple()
{
    BYTE r,g,b,gray;
    BYTE iWH=255,iBW=0,iGRAY=128;
    int isize,hist[256],thr[10];
    FillMemory(hist,sizeof(int)*256,0);
    // ヒストグラムの作成[濃淡化]
    for(int i=0;i<iHeight;i++) for(int j=0;j<iWidth;j++) {
        b=lpOrgBMP[j*3+i*iLength];
        g=lpOrgBMP[j*3+i*iLength+1];
        r=lpOrgBMP[j*3+i*iLength+2];
        gray=(BYTE)(r*0.299+g*0.587+b*0.144);
        FillMemory(lpBMP+j*3+i*iLength,3,gray);
        hist[gray]++;
    }
    // [3..]値化最適しきい値の計算
    isize = iWidth*iHeight;
    calc_opthmdthr(3,256,isize,hist,thr);
    // 3値画像の作成
    for(int i=0;i<iHeight;i++) for(int j=0;j<iWidth;j++) {
        gray=lpBMP[j*3+i*iLength];
        if(gray>thr[2]){
            FillMemory(lpBMP+j*3+i*iLength,3,iWH);
        } else if(gray>thr[1]) {
            FillMemory(lpBMP+j*3+i*iLength,3,iGRAY);
        } else {
            FillMemory(lpBMP+j*3+i*iLength,3,iBW);
        }
        hist[gray]++;
    }
}
//-----------------------------------------------------------------
// ビットマップの色を反転
//-----------------------------------------------------------------
void revColor(void)
{
    // 反転処理
    for(int i=0;i<iHeight;i++) for(int j=0;j<iWidth;j++) {
        lpBMP[j*3+i*iLength]   = 255-lpOrgBMP[j*3+i*iLength];
        lpBMP[j*3+i*iLength+1] = 255-lpOrgBMP[j*3+i*iLength+1];
        lpBMP[j*3+i*iLength+2] = 255-lpOrgBMP[j*3+i*iLength+2];
    }
}

inserted by FC2 system