使用可分离的内核时,为什么我的sobel滤波器输出如此明亮?

时间:2019-01-02 00:21:00

标签: c++ image-processing computer-vision convolution sobel

我正在尝试从头开始实现Sobel过滤器。我正在使用https://en.wikipedia.org/wiki/Sobel_operator#Technical_details中所述的可分离过滤器。

这是我的原始图像转换为灰度图像: greyscale image

我的Sobel X梯度输出很好:x-gradient sobel filtered image

但是,我的Sobel y梯度图像不正确:y-gradient sobel filtered image

在我看来,像素值太高。这是在与内核[1, 2, 1]进行水平卷积之后,而在垂直卷积之前的y-gradient horizontal only

上的y梯度图像。

这是代码。请注意,对于y梯度,我只是复制粘贴了x梯度代码,并交换了首先使用哪个内核(如Wikipedia页面所示):

int sobel_1[3] = {1, 0, -1};
int sobel_2[3] = {1, 2, 1};

Image Image::sobel_x(){
    Image grayscale = this->grayscale();
    Image sobel_x = Image(m_width, m_height, m_max);

    int r_delta[3] = {-1, 0, 1};
    int c_delta[3] = {-1, 0, 1};

    for (int row = 0; row < m_height; row++){
        for (int col = 0; col < m_width; col++){
            Color new_color = Color();

            for (int i = 0; i < 3; i++){   
                int new_c = col + c_delta[i]; 

                if (new_c >= 0 && new_c < m_width){
                    new_color = new_color + (grayscale.getRGB(row, new_c) * sobel_1[i]);
                }
            }

            new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
            new_color.clamp();

            sobel_x.setColor(row, col, new_color);
        }
    }

    for (int row = 0; row < m_height; row++){
        for (int col = 0; col < m_width; col++){
            Color new_color = Color();

            for (int i = 0; i < 3; i++){
                int new_r = row + r_delta[i]; 

                if (new_r >= 0 && new_r < m_height){
                    new_color = new_color + (sobel_x.getRGB(new_r, col) * sobel_2[i]);
                }
            }

            new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
            new_color.clamp();
            new_color = new_color / 8;

            sobel_x.setColor(row, col, new_color);
        }
    }

    return sobel_x;
}

Image Image::sobel_y(){
    Image grayscale = this->grayscale();
    Image sobel_y = Image(m_width, m_height, m_max);

    int r_delta[3] = {-1, 0, 1};
    int c_delta[3] = {-1, 0, 1};

    for (int row = 0; row < m_height; row++){
        for (int col = 0; col < m_width; col++){
            Color new_color = Color();

            for (int i = 0; i < 3; i++){   
                int new_c = col + c_delta[i]; 

                if (new_c >= 0 && new_c < m_width){
                    new_color = new_color + (grayscale.getRGB(row, new_c) * sobel_2[i]);
                }
            }

            new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
            new_color.clamp();

            sobel_y.setColor(row, col, new_color);
        }
    }

    for (int row = 0; row < m_height; row++){
        for (int col = 0; col < m_width; col++){
            Color new_color = Color();

            for (int i = 0; i < 3; i++){
                int new_r = row + r_delta[i]; 

                if (new_r >= 0 && new_r < m_height){
                    new_color = new_color + (sobel_y.getRGB(new_r, col) * sobel_1[i]);
                }
            }

            new_color = Color(abs(new_color.get_r()), abs(new_color.get_g()), abs(new_color.get_b()));
            new_color.clamp();
            new_color = new_color / 8;

            sobel_y.setColor(row, col, new_color);
        }
    }

    return sobel_y;
}

0 个答案:

没有答案