「ビットマップ画像の画像処理」のプログラムをより、画像処理に特化できるように改良した例です。処理後の画像も[保存]ボタンにより保存することができるようになりました。
以下のソース部分を変更すればウィンドウ内のメニューが自動的に追加され、処理を選択することができます。
//----------------------------------------------------------------- // メニューへの追加内容 //----------------------------------------------------------------- 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: // 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]; } } |