
プログラミング初心者で、プログラミングが苦手な者です。
エクリプスというソフトを使って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ランキング
-
jdbcでinsert,delete,createをe...
-
プログラミングの問題です。大...
-
Googleログインボタンのデザイ...
-
JDONWROADER2のエラー修復
-
「main メソッドを持つクラスが...
-
Eclipse 動的プロジェクトで404...
-
正規表現について質問です。 カ...
-
スプレッドシートからリマイン...
-
googleスプレッドシートのスク...
-
googleスプレッドシートのGASに...
-
Verilogについて質問です。この...
-
論理回路設計をVerilogで行う問...
-
ゲーム開発の入門書を探しています
-
session,requestはjspで未定義...
-
サーブレットをapacheで公開す...
-
下記のリストならno002が含まれ...
-
is this even a thing?
-
JAの支部?地域の農協のカード...
-
えハミルトン路と全域木のちが...
-
CSV出力を画面から選択したデー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
JDONWROADER2のエラー修復
-
Googleログインボタンのデザイ...
-
配列にnullを代入すると、null...
-
jdbcでinsert,delete,createをe...
-
「main メソッドを持つクラスが...
-
プログラミングの問題です。大...
-
eclipseで作ったプログラムを他...
-
正規表現について質問です。 カ...
-
Eclipse 動的プロジェクトで404...
-
マイクラでPythonのプログラミ...
-
jdk17.06のインストーラーが起...
-
自作Androidアプリのデータ引き...
-
直し方について教えて頂きたい...
-
eclipse実行ができない
-
サーブレットをapacheで公開す...
-
あんまりお料理しないのに台所...
-
CSV出力を画面から選択したデー...
-
次のhtml・cssでspan内の文字を...
-
問題作成のWebアプリの作り方を...
-
ゲーム開発の入門書を探しています
おすすめ情報