プログラミング初心者で、プログラミングが苦手な者です。
エクリプスというソフトを使って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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- Java Java 配列<選挙> 4 2023/07/31 15:07
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SwingでJtableのヘッダ行が表示...
-
java spring でエラーが出て困...
-
「配列定数は、イニシャライザ...
-
Javaのファイル名チェックについて
-
DataSet(DataTable)の使い方
-
Java3Dで円錐台を描く方法を教...
-
共有メモリについて
-
C#で指定した月の最後の日を取...
-
JAVA エラー 式の開始が不正で...
-
VC++2008 フォーム間の変数の受...
-
クラスの設計の問題
-
各店舗全て、リンゴは1個150円...
-
iアプリでバイナリデータを16進...
-
javaのエラーの意味がわかりま...
-
C言語からJavaに書き換えの質...
-
javaで電卓を作りたいのですが...
-
javaでべき乗余
-
先入れ先出し法のプログラミン...
-
c# デリゲート関連の命名について
-
javaの画像解析(RGB)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「配列定数は、イニシャライザ...
-
Javaで電卓を作りたい
-
式の型は配列型で int に解決済...
-
javaでカレンダー作成
-
JAVAでCの関数ポインタのような...
-
JAVA エラー 式の開始が不正で...
-
java spring でエラーが出て困...
-
6桁の数字を重複なしでランダム...
-
c# デリゲート関連の命名について
-
C++からC#のdllを参照する際、...
-
メインが含まれていません
-
(Swing)JTextFieldを半角のみ入...
-
DataSet(DataTable)の使い方
-
JUnit4のアノテーションについて
-
三目並べ(Tick-Tack-Toe)をJav...
-
初心者ですが、今javaで簡単な...
-
javaでcsvファイル読込時の改行...
-
classを使って座標軸を求めるコ...
-
C#で実行時にメソッドの返り値...
-
Java 初心者 int型の取り扱い方
おすすめ情報