プロが教える店舗&オフィスのセキュリティ対策術

はじめまして。プログラミング課題でグレースケール画像の誤差拡散法を用いた二値化をプログラミングしています。
しかし、書いてあるとおりにプログラミングしても真っ白になってしまいます。どうしてでしょうか?
主なソースコードは

対象画素の画素値:f
誤差:e
-----------------------------------------
for(i = 0 ; i < wide ; i++){
for(j = 0 ; j < high ; j++){
e = f[i][j] - 255;

if(f[i][j] > 127)
f[i][j] = 255;

else
f[i][j] = 0;

f[i+1] += 5/16*e;
f[i+1][j+1] += 3/16*e;
f[i][j+1] += 5/16*e;
}
}
-----------------------------------
というとても簡素な構造になっています。右端とか下とかの場合分けは今省略させてもらいました。
私の考察としてどんどん誤差が累積されるので真っ白になってもおかしくないと思うのですが。教科書やネットページを見てもこのようになっている感じがします。どこがおかしいのか教えてください。よろしくお願いします。

A 回答 (4件)

#3です。


アルゴリズム間違ってませんか?
【二値化 誤差拡散法】で検索かけたら
「Floyd & Steinberg型」と「Javis,Judice,& Ninke型」というのが見つかりました。
そこのサンプルと比較すると、
・誤差の計算方法
・誤差の分散方法
が提示したソースと異なっているようです。
    • good
    • 0

画像処理の手法については知識が無いのですが


提示されたソースを見て。
f[i+1] += 5/16*e;
のところだけ1次元配列になっていますが
これは転記ミスでしょうか?
    • good
    • 0

このままだと正確な判断ができませんので、


1.使用している変数の型をすべて提示してください。
2.使用しているOS及びコンパイラを提示してください。
3.念のため確認しますが、このソースは、実際のプログラムのソースをコピーして、張りつけたものでしょうか。(手で入力して転記ミスはないですね)
上記の補足をお願いします。

この回答への補足

OSはLinuxのRedHutです(つづり間違ってたらすいません)
コンパイラはわかりませんがmakeを使いました。
無知で申し訳ないです。

補足します。実際のソースコードは以下のとおりです。
いろいろ関数使ってるんですけど
// 入力データ(piInputmData)を誤差拡散方を用いて二値化して、
// 出力データ(piOutputData)に保存
のところから誤差拡散法に入ります。
問題は一次元配列になっているところです。理由はわかりませんが位置次元でやれとのことなので・・・。

void Error_diffusion_method(void){

int iWidth, iHeight, iMaxValue; // 画像の幅,高さ,解像度
int * piInputData; // 入力データの格納
int * piOutputData; // 画像処理したデータを格納
int e; // 誤差を格納
int i; // ループカウンタ

// 二値画像
printf("\n**** Error diffusin method Image *****\n");

// PGM形式の入力データの読み込み
piInputData = ReadPgm(&iWidth, &iHeight, &iMaxValue);

// 出力データ(1次元)のメモリ領域の確保
// piOutputData[iWidth*iHeight]
piOutputData = (int *)malloc(iWidth*iHeight*sizeof(int));

// 入力データ(piInputmData)を誤差拡散方を用いて二値化して、
// 出力データ(piOutputData)に保存
for(i = 0; i < iWidth*iHeight; i++){
e = 255 - piInputData[i];

//拡散処理前の対象画素処理
if(piInputData[i] <= 127){
piInputData[i] = 0;
}
else{
piInputData[i] = 255;
}
piOutputData[i] = piInputData[i];

//誤差拡散処理

//1.最後の画素の時
if(i == (iWidth*iHeight-1)){
}

//2.最下行の時
else if(i >= (iWidth*iHeight - iWidth)){
piInputData[i+1] += e*3/16;
}

//3.右端の時
else if(((i+1) % iWidth) == 0){
piInputData[i+iWidth] += e*3/16;
}

//4.通常状態
else{
piInputData[i+1] += e*3/16;
piInputData[i+iWidth] += e*3/16;
piInputData[i+iWidth+1] += e*5/16;
}
}


// 入力データを保存しているメモリ領域を解放
FreePgm(piInputData);

// PPM形式のファイルに出力データを出力
WritePgm(piOutputData, iWidth, iHeight, iMaxValue);

// 出力データを保存しているメモリ領域を解放
FreePgm(piOutputData);
}

となっています。

補足日時:2006/11/15 13:41
    • good
    • 0

詳しくはみてませんが、


> 5/16*e
これが必ず0になるのが原因ではないですか?
(整数演算なので5/16は0。0に何をかけても0。)

この回答への補足

あ、そうですね。実際のソースコードも
e*5/16
でした。
しかし上記のようにしても結果は同じ・・・申し訳ありません。
回答ありがとうございました。

補足日時:2006/11/13 20:17
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!