電子書籍の厳選無料作品が豊富!

プログラミング初心者で、プログラミングが苦手な者です。
エクリプスというソフトを使ってJavaでsobelフィルタの画像処理を作っているのですが
どうしても出来ない部分があります。
下記のコードで作っているのですがうまく動作が出来ないようです。


import org.eclipse.swt.graphics.*;

// フィルタクラス
public class ImgFil{



// Sobelフィルタ

public static Image filso(Image image) {
int[] iDx = {- 1, 0, -1, -1, 0, 1, -1, 0, 1 };
int[] iDy = { -1, -1, -1, 0, 0, 0, 1, 1, 1 };
int[] iW1 = { -1, 0, 1, -2, 0, 2, -1, 0, 1 };
int[] iW2 = { -1, -2, -1, 0, 0, 0, 1, 2, 1 };

ImageData imd = image.getImageData();// 画像データ
ImageData imd2 =image.getImageData();// 変換後データを格納するImageData


// 画像の幅、高さ
int wid = imd.width;
int hgt = imd.height;

// 空間フィルタは周りの画素を使うため、
// はみでないように(1~wid-1)と(1~hgt-1)でループ
for (int y = 1; y < hgt-1; y++) {
for (int x = 1; x < wid-1; x++) {
for(int i = 0; i < 9; i++) {
// 中心座標の色
int iC0 = imd.getPixel(x, y);
int iR0 = PixelColor.getR(iC0);
int iG0 = PixelColor.getG(iC0);
int iB0 = PixelColor.getB(iC0);

// 右どなりの色
int iCr = imd.getPixel(x+1, y);
int iRr = PixelColor.getR(iCr);
int iGr = PixelColor.getG(iCr);
int iBr = PixelColor.getB(iCr);

// 下どなりの色
int iCu = imd.getPixel(x, y+1);
int iRu = PixelColor.getR(iCu);
int iGu = PixelColor.getG(iCu);
int iBu = PixelColor.getB(iCu);

// 合計値を加算していく変数
int iRsum1 = 0;
int iGsum1 = 0;
int iBsum1 = 0;
int iRsum2 = 0;
int iGsum2 = 0;
int iBsum2 = 0;


// RGBに分解して取得
int iR = PixelColor.getR(iC);
int iG = PixelColor.getG(iC);
int iB = PixelColor.getB(iC);

// 累積加算1
int iRsum + = iR * iW1[i];
int iGsum + = iG * iW1[i];
int iBsum + = iB * iW1[i];

// 累積加算2
int iRsum + = iR * iW2[i];
int iGsum + = iG * iW2[i];
int iBsum + = iB * iW2[i];
}

// エッジ強度を計算
// Math.abs(...)は絶対値を求める関数
int iRd = Math.abs(iRr-iRO) + Math.abs(iRu-iR0);
int iGd = Math.abs(iGr-iG0) + Math.abs(iGu-iG0);
int iBd = Math.abs(iBr-iB0) + Math.abs(iBu-iB0);

int iRd2 = Math.abs(iRr-iR0) + Math.abs(iRu-iR0);
int iGd2 = Math.abs(iGr-iG0) + Math.abs(iGu-iG0);
int iBd2 = Math.abs(iBr-iB0) + Math.abs(iBu-iB0);

// 合計値を個数で割る
int iPRd = iRd+iRd2 ;
int iPGd = iRd+iRd2 ;
int iPBd = iRd+iRd2 ;
// 上限値のチェック
// (255を超すとエラーになるので255に揃える)
if (iPRd > 255){
iRd = 255;
}
if (iPGd > 255){
iPGd = 255;
}
if (iPBd > 255){
iPBd = 255;
}
// 下限値のチェック
// (255を超すとエラーになるので255に揃える)
if (iPRd < 0){
iPRd = 0;
}
if (iPGd < 0){
iPGd = 0;
}
if (iPBd < 0){
iPBd = 0;
}
// カラー値の作成
int iCd = PixelColor.setRGB(iRd, iGd, iBd);
// カラー値をimd2(変換後データ)に設定
imd2.setPixel(x, y, iCd);
}
}

// 変換後データimd2を使って、新しいImageを作成
Image newImage = new Image(null, imd2);
// 新しいImageを返す
return newImage;
}




}


エクリプスで見るとRGBに分解して取得、累積加算、
エッジ強度の計算のところのコードに
赤波線のエラー表示が出ていたので
その部分の処理がうまく出来ていないのではと思います。

sobelプログラムを動作させるためのファイルは全部で4つで

一つは画像を呼び出すボタンファイル。
二つ目に画像処理を起動するファイル。
三つ目に画像表示用のファイル。
RGBの値を取得するファイル。
で構成されています。

今回問題があって質問したいのは
二つ目の画像処理を起動するファイルのコードです。
自分でもインターネット等で似たような構成のソースコードを
参考にしてやってみたのですが良く分かりませんでした。
プログラミングが苦手なので
出来る限り分かりやすく解答していただけれると助かります。

A 回答 (2件)

・配列 iDx と iDy はたぶん座標(x,y)からみた中心画素とその周囲8画素の相対座標ですね。



・iRsum1 から iBsum2 までの変数へ0を代入している部分は、変数iのループの中ではなく、ループの直前に書きましょう。iのループが終わった後で、これらの合計値を使うので。

・下記の部分は、配列 iDx と iDy があるので必要ないです。代わりに iDx と iDy を使って、中心画素と周囲8画素の色を取得しましょう。

 // 中心座標の色
 ...(略)...
 // 右どなりの色
 ...(略)...
 // 下どなりの色
 ...(略)...

・「累積加算1」「累積加算2」のところは必要な処理ですが、コンパイルエラーになりますよね?

・エッジ強度ですが、Sobelフィルタなら√(sum1の自乗 + sum2の二乗)ではないでしょうか。また、後述のようにエッジ強度とその最大値・最小値を記録しておいた方がよいでしょう。エッジ強度については、あらかじめ画像と同じサイズの配列を用意しておいて。

・256階調の画像で出力するなら、エッジ強度を単純に0未満と256以上を切り捨てない方がよいでしょう。画像によりますが、エッジ強度の値のスケールが256階調からかけ離れる可能性があります。その対処には二回目のx,yループが必要です。一回目のx,yループで調べたエッジ強度の最小値・最大値を使って、エッジ強度×(255.0 / (最大値 - 最小値)) - 最小値、のようにエッジ強度を255階調に調整します。(もしエッジ強度本来の値が必要なら、別な出力方法を考えましょう)
    • good
    • 0

Sobelフィルターって単純に3x3にフィルタを適用するだけですが。


> // 右どなりの色
> // 下どなりの色
ってどっからでてきました?

-1 -2 -1
0 0 0
1 2 1

というフィルタを

I(x-1,y-1) I(x,y-1) I(x+1,y-1)
I(x-1,y) I(x,y) I(x+1,y)
I(x-1,y+1) I(x,y+1) I(x+1,y+1)

という画像の「I(x,y)」に適用したら、どんな計算になるか、式を書いてみましょう。
このプログラムに、この式を計算しているところが見当りません。

> for(int i = 0; i < 9; i++) {
のループで計算するつもりなのでしょうが、I(x,y)しか出てきません。他のI(x-1,y-1)等を得るにはどうすればいいか考えましょう。
> int[] iDx = {- 1, 0, -1, -1, 0, 1, -1, 0, 1 };
> int[] iDy = { -1, -1, -1, 0, 0, 0, 1, 1, 1 };
と、なんか使ってない配列がありますね
    • good
    • 0

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