java – Canny的算法:滞后误差函数

前端之家收集整理的这篇文章主要介绍了java – Canny的算法:滞后误差函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在写Canny的算法,我似乎有一个滞后问题.阈值似乎正在处理,但是我的滞后似乎根本不起作用.以及由于一些奇怪的原因删除弱的方法.请帮忙!

低@ 10

高@ 75

在滞后后,问题A,边缘没有加强,方法执行滞后;使用方法removeWeak不会删除B弱边缘.

方法的源代码如下:

import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;

class CannyMethod {

private static final float[] sobelX = { 1.0f,0.0f,-1.0f,2.0f,-2.0f,1.0f,-1.0f};
private static final float[] sobelY = { 1.0f,-1.0f};
private static int low,high;


public CannyMethod() {}

private ConvolveOp getSobel(boolean xy) {
    Kernel kernel;
    if (xy) kernel = new Kernel(3,3,sobelX);
    else kernel = new Kernel(3,sobelY);

    return new ConvolveOp(kernel,ConvolveOp.EDGE_ZERO_FILL,null);
}

public BufferedImage getCannyFilter(BufferedImage img) {
    return getCannyFilter(img,low,high);
}

public BufferedImage getCannyFilter(BufferedImage img,int l,int h) {
    int width = img.getWidth();
    int height = img.getHeight();
    low = l;
    high = h;

    int size = width * height;
    int[] x = new int[size];
    int[] y = new int[size];
    int[] pixelM = new int[size];
    double[] pixelD = new double[size];
    int[] pixelNew = new int[size];

    BufferedImage sobelXImg = getSobel(true).filter(img,null);
    BufferedImage sobelYImg = getSobel(false).filter(img,null);


    // returns arrays for x and y direction after convultion with Sobel Operator
    sobelXImg.getRaster().getPixels(0,width,height,x);
    sobelYImg.getRaster().getPixels(0,y);

// Calculates Gradient and Magnitude
    for(int i = 0; i < size; i++) {
        pixelM[i] = (int) Math.hypot(x[i],y[i]);
        pixelD[i] = Math.atan2((double) y[i],(double) x[i]);
    }

//Operations for Canny Algorithm takes magnitude and gradient and input into new array fo WritableRaster
    normalizeDirection(pixelD);
    nonMaximaSupression(pixelM,pixelD,pixelNew,height);
    performHysteresis(pixelNew,width);
    removeWeak(pixelNew);

    BufferedImage result = 
        new BufferedImage(width,BufferedImage.TYPE_BYTE_GRAY);
    result.getRaster().setPixels(0,pixelNew);

    return result;
}

private void normalizeDirection(double[] dArray) {
//Round degrees

    double pi = Math.PI;
    for(double i : dArray) {
        if (i < pi/8d && i >= -pi/8d) i = 0;
        else if (i < 3d*pi/8d && i >= pi/8d) i = 45;
        else if (i < -3d*pi/8d || i >= 3d*pi/8d) i = 90;
        else if (i < -pi/8d && i >= -3d*pi/8d) i = 135;
    }
}

private void nonMaximaSupression(int[] pixelM,double[] pixelD,int[] pixelNew,int width,int height) {
//non-Maxima Supression
//Since array is not in 2-D,positions are calulated with width - functions properly

    for(int i = 0; i < pixelNew.length; i++) {
        if (i % width == 0 || (i + 1) % width == 0 ||
            i <= width || i >= width * height - 1) pixelNew[i] = 0;
        else {
            switch ((int) pixelD[i]) {
                case 0:  if (pixelM[i] > pixelM[i+1] 
                            && pixelM[i] > pixelM[i-1])
                            setPixel(i,pixelM[i],pixelNew);
                         else pixelNew[i] = 0;
                         break;
                case 45: if (pixelM[i] > pixelM[i+(width-1)] 
                            && pixelM[i] > pixelM[i-(width-1)])
                            setPixel(i,pixelNew);
                         else pixelNew[i] = 0;
                         break;
                case 90: if (pixelM[i] > pixelM[i+width] 
                            && pixelM[i] > pixelM[i-width])
                            setPixel(i,pixelNew);
                         else pixelNew[i] = 0;
                         break;
                case 135:if (pixelM[i] > pixelM[i+width] 
                            && pixelM[i] > pixelM[i-width])
                            setPixel(i,pixelNew);
                         else pixelNew[i] = 0;
                         break;
                default: pixelNew[i] = 0;
            }
        }
    }
}

private void performHysteresis(int[] array,int width) {
//performs hysteresis

    int[] temp;
    for(int i = width; i < array.length - width; i++) {
        if (i % width == 0 || (i + 1) % width == 0) {}
        else {
            if (array[i] == 255) {
    //found strong one,track surrounding weak ones
    //temp is the positions of surrounding pixels
                temp = new int[] 
                    {i - (width + 1),i - width,i - (width - 1),i - 1,i + 1,i + (width - 1),i + width,i + (width + 1)};
                trackWeak(array,temp,width);
            }
        }
    }
}

private void trackWeak(int[] array,int[] pos,int width) {
    int[] temp;
    for (int i : pos) {
        if (array[i] > 0 && array[i] < 255) {
            array[i] = 255;
    //set weak one to strong one

            if (i % width == 0 || (i + 1) % width == 0) {}
            else {
    //temp is the positions of surrounding pixels
                temp = new int[]
                    {i - (width + 1),width);
            }
        }
    }
}

private void removeWeak(int[] array) {
//remove remaining weak ones from lew Threshold

    for(int i : array) {
        if (i < 255) {i = 0;}
    }
}

private void setPixel(int pos,int value,int[] pixelNew) {
    if (value > high) pixelNew[pos] = 255;
    else if (value > low) pixelNew[pos] = 128;
    else pixelNew[pos] = 0;
}

public void setThreshold(int l,int h) {
    low = l;
    high = h;
}
}

解决方法

我想到了.迟滞是有效的,考虑到图像的质量,这很难说.

至于删除弱,我使用增强的for循环,我开始看到只获得并更改了元素的副本,而不是数组本身的元素.一旦我将其更改为常规for循环,它就可以了!

原文链接:https://www.f2er.com/java/129586.html

猜你在找的Java相关文章