を......................あなたのコードに関する問題。まず、コードでは、カラー整数そのものではなく、計算で色成分(R、G、B)を使用することになっています。
int val00=image.getRGB(i-1,j-1);
//Should be
int val00 = getGrayScale(image.getRGB(i - 1, j - 1));
Where getGrayScale() gives the luminance of the color in gray scale, otherwise you can use all three components individually.
第二の問題は、あなたが直接色にgcal or g
勾配値を設定しているということです。これはコンポーネントだけでなく、g<<16 | g<<8 | g
を使用して色に変換する必要があります。
しかし、gは必ずしも範囲0-255
にあるわけではないので、最大g
を見つけてから、すべてのグラジエントを255/max(g)
で正規化することで注意する必要があります。
以下は動作コードです。
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SobelTest {
public static void main(String args[]) throws IOException {
System.out.println("Started");
/*System.out.println("Enter the file name :");
Scanner ne1 = new Scanner(System.in);
String filename = ne1.nextLine();*/
String filename = "engine.png";
File file = new File(filename);
BufferedImage image = ImageIO.read(file);
int x = image.getWidth();
int y = image.getHeight();
int maxGval = 0;
int[][] edgeColors = new int[x][y];
int maxGradient = -1;
for (int i = 1; i < x - 1; i++) {
for (int j = 1; j < y - 1; j++) {
int val00 = getGrayScale(image.getRGB(i - 1, j - 1));
int val01 = getGrayScale(image.getRGB(i - 1, j));
int val02 = getGrayScale(image.getRGB(i - 1, j + 1));
int val10 = getGrayScale(image.getRGB(i, j - 1));
int val11 = getGrayScale(image.getRGB(i, j));
int val12 = getGrayScale(image.getRGB(i, j + 1));
int val20 = getGrayScale(image.getRGB(i + 1, j - 1));
int val21 = getGrayScale(image.getRGB(i + 1, j));
int val22 = getGrayScale(image.getRGB(i + 1, j + 1));
int gx = ((-1 * val00) + (0 * val01) + (1 * val02))
+ ((-2 * val10) + (0 * val11) + (2 * val12))
+ ((-1 * val20) + (0 * val21) + (1 * val22));
int gy = ((-1 * val00) + (-2 * val01) + (-1 * val02))
+ ((0 * val10) + (0 * val11) + (0 * val12))
+ ((1 * val20) + (2 * val21) + (1 * val22));
double gval = Math.sqrt((gx * gx) + (gy * gy));
int g = (int) gval;
if(maxGradient < g) {
maxGradient = g;
}
edgeColors[i][j] = g;
}
}
double scale = 255.0/maxGradient;
for (int i = 1; i < x - 1; i++) {
for (int j = 1; j < y - 1; j++) {
int edgeColor = edgeColors[i][j];
edgeColor = (int)(edgeColor * scale);
edgeColor = 0xff000000 | (edgeColor << 16) | (edgeColor << 8) | edgeColor;
image.setRGB(i, j, edgeColor);
}
}
File outputfile = new File("sobel.png");
ImageIO.write(image, "png", outputfile);
System.out.println("max : " + maxGradient);
System.out.println("Finished");
}
public static int getGrayScale(int rgb) {
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = (rgb) & 0xff;
//from https://en.wikipedia.org/wiki/Grayscale, calculating luminance
int gray = (int)(0.2126 * r + 0.7152 * g + 0.0722 * b);
//int gray = (r + g + b)/3;
return gray;
}
}
出力
編集
第二の画像は、最初の1に反対アルファチャンネルが含まれている、以下の両方の詳細を参照してください。
#Engine
type = 5 ColorModel: #pixelBits = 24 numComponents = 3 has alpha = false
#Type 5 is BufferedImage.TYPE_3BYTE_BGR
#Girl
type = 6 ColorModel: #pixelBits = 32 numComponents = 4 has alpha = true
#type 6 is BufferedImagef.TYPE_4BYTE_ABGR
第2の画像にはアルファ成分が含まれており、アルファを設定していないので完全に透明になります。
コードの次の部分を変更して、アルファを不透明にする必要があります。
edgeColor = (edgeColor << 16) | (edgeColor << 8) | edgeColor;
//Should be
edgeColor = 0xff000000 | (edgeColor << 16) | (edgeColor << 8) | edgeColor;
これまでのコードを変更しました。
ここに変更が出力されます。
あなたのコメントでは、画像のようにエッジが、あなたは勾配の方向に基づいてグループのエッジにあり、弱いエッジを無視するように、適切なしきい値を使用します取得します。
レコードのためだけに:あなたはここに来ることはできません。あなたは良い質問をしようとします。私たちは何をしているのかを見ます。しかし、まれにそれは誰かがあなたの上に働く解決策を落とすことを意味します!その意味では、単にそのようなステートメントを避けてください。彼らは少し上に来る可能性があります...無礼... – GhostCat
ごめんなさい –
ヒント:あなたの質問を編集することができます;-) – GhostCat