![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
プログラミング初心者で、プログラミングが苦手な者です。
エクリプスというソフトを使って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件)
- 最新から表示
- 回答順に表示
No.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階調に調整します。(もしエッジ強度本来の値が必要なら、別な出力方法を考えましょう)
No.1
- 回答日時:
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 };
と、なんか使ってない配列がありますね
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Java 初心者 int型の取り扱い方
-
「配列定数は、イニシャライザ...
-
JFrameをフェードイン・フェー...
-
DataSet(DataTable)の使い方
-
javaでcsvファイル読込時の改行...
-
javaでカレンダー作成
-
アクセス用クラスを利用した登...
-
各店舗全て、リンゴは1個150円...
-
フィボナッチ数列 java
-
java 長さの異なる配列の代入
-
(Swing)JTextFieldを半角のみ入...
-
西暦 -> 年号、年号 -> 西暦の...
-
javaのfor文
-
Javaで簡単なアニメーションを...
-
【C#】クラスのメンバ変数のア...
-
javaで質問です。 文字列2023/2...
-
Java、2の0乗~10乗の表示
-
ORA-01858: 数値を指定する箇所...
-
Enterキーでボタンを押すにはど...
-
改行の判定方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「配列定数は、イニシャライザ...
-
java spring でエラーが出て困...
-
Java 初心者 int型の取り扱い方
-
式の型は配列型で int に解決済...
-
DataSet(DataTable)の使い方
-
C#で、デリゲートからその関数...
-
6桁の数字を重複なしでランダム...
-
C#で実行時にメソッドの返り値...
-
JUnit4のアノテーションについて
-
行の途中から読み込む方法
-
Javaで電卓を作りたい
-
SwingでJtableのヘッダ行が表示...
-
javaでcsvファイル読込時の改行...
-
ビープ音をなめらかに鳴らしたい
-
c# デリゲート関連の命名について
-
javaでカレンダー作成
-
intが負の時に投げる例外はあり...
-
デスクトップのアイコンの位置...
-
【C#】フォームをなめらかに移動
-
java 長さの異なる配列の代入
おすすめ情報