java - 实现索贝尔算法

标签 java algorithm bufferedimage sobel

<分区>

我想实现Sobel算法。

首先

我获取输入图像的灰度数据并将数据放入mGrayData:

  BufferedImage mImage, mNewImage;
  for (int i = 0; i < mHeight; i++) {
        for (int j = 0; j < mWidth; j++) {
            int rgb = mImage.getRGB(j, i);
            int newRgb;
             int r = (rgb >> 16) & 0xff;
            int g = (rgb >> 8) & 0xff;
            int b = rgb & 0xff;
            int grayLevel = (r + g + b) / 3;
            int gray = (grayLevel << 16) + (grayLevel << 8) + grayLevel;
            mGrayData[i * mWidth + j] = gray;
        }
    }

然后

我计算每个点的梯度:

 int[] gradient = new int[mWidth * mHeight];
    for (int x=1;x<mWidth-1;x++){
        for (int y=1;y<mHeight-1;y++){
            int grayX = getGrayPoint(x+1,y-1)+2*getGrayPoint(x+1,y)+getGrayPoint(x+1,y+1)-
                    (getGrayPoint(x-1,y-1)+2*getGrayPoint(x-1,y)+getGrayPoint(x-1,y+1));

            int grayY = (getGrayPoint(x-1, y+1) + 2*getGrayPoint(x,y+1)+getGrayPoint(x+1,y+1))-
                    (getGrayPoint(x-1,y-1) + 2*getGrayPoint(x,y-1) + getGrayPoint(x+1,y-1));
            gradient[x+y*mWidth] = (int) Math.sqrt(grayX*grayX+grayY*grayY);
        }
    }

方法梯度(x,y):

 private int getGrayPoint(int x,int y){
    return mGrayData[x+y*mWidth];
}

问题

输入图像:

过滤后:

现在我该如何实现呢?

编辑:

我不知道如何使用梯度数据。我试试这个:

   int[] gradient = getGradient();
    int maxGradient = gradient[0];
    for (int i=0;i<gradient.length;i++){
        if (gradient[i]>maxGradient)
            maxGradient = gradient[i];
    }
    float scaleFactor = 255.0f / maxGradient;
    for (int y = 1; y < mHeight - 1; ++y)
        for (int x = 1; x < mWidth - 1; ++x)
            if (Math.round(scaleFactor * gradient[y * mWidth + x]) >= mThreshold)
            {
                mNewImage.setRGB(x, y, 0x000000);
            }else {
                mNewImage.setRGB(x,y,mGrayData[y * mWidth + x]);
            }
    File file = new File("D:\\Documents\\Pictures\\engine3.png");
    if (!file.exists()) {
        file.getParentFile().mkdir();
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    try {
        ImageIO.write(mNewImage, "png", file);
    } catch (IOException e) {
        e.printStackTrace();
    }

然后我得到图像:

最佳答案

看来您在梯度计算中使用了错误的数据。您的 mGrayData 包含整数值 0xAXXX,其中 A 是 alpha,X 是灰度值(计算为 r、g、b 的平均值)。

改为使用

mGrayData[i * mWidth + j] = average;

第二次编辑:
建议:

private int getGrayPoint(int x,int y){
    return mGrayData[x+y*mWidth] & 0xff;
 }

关于java - 实现索贝尔算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39326328/

相关文章:

java - Java 中的 BufferedImage 到 OpenCV Mat 中

java - 自定义 bean 验证约束和 persist() 验证

algorithm - 阿贝尔群中的最小成本因式分解

Java BufferedImage 序列化

java - 如何在 BufferedImage 中用另一种颜色替换颜色

algorithm - 我如何从文本文件中找到彼此相邻的前 3 个单词

java - Spring数据存储库中的正确继承

java - SDN 4-RC1 : RelationRepository. save(relationshipEntity) 不在图形中保存关系实体

java - 100 个数字的阶乘

c++ - 派对日程-经典背包