图像处理 - 实现Sobel滤波器

Ahm*_*osh 30 image-processing edge-detection

我有一个任务来实现Sobel滤波器,正如你所知,它是一个用于边缘检测的图像处理滤波器.但不幸的是,我没有图像处理领域的经验,我甚至不知道图像在计算机中的表现方式.完全没有这个领域的知识.

我已经阅读了一些论文和PDF,但他们关注的很多主题我认为我可能不需要它们来完成我的任务.

我很乐意知道您的建议,或者是否有任何特定的论文,PDF,教程或快速指南.

谢谢

编辑:

谢谢大家:)我们的工作成果可以从这里下载.

aze*_*r89 28

这很简单,您只需要使用Sobel滤镜对图像进行卷积.Sobel滤波器有两个内核,x方向内核和y方向内核.x方向内核检测水平边缘,y方向内核检测垂直边缘.

x方向内核(大小为3x3)

float kernelx[3][3] = {{-1, 0, 1}, 
                       {-2, 0, 2}, 
                       {-1, 0, 1}};
Run Code Online (Sandbox Code Playgroud)

y方向内核

float kernely[3][3] = {{-1, -2, -1}, 
                        {0,  0,  0}, 
                        {1,  2,  1}};
Run Code Online (Sandbox Code Playgroud)

要计算像素(x,y)处的卷积,请定义大小等于内核大小的窗口(用于计算x中的幅度和y中的幅度的源代码是相同的):

double magX = 0.0; // this is your magnitude

for(int a = 0; a < 3; a++)
{
    for(int b = 0; b < 3; b++)
    {            
        int xn = x + a - 1;
        int yn = y + b - 1;

        int index = xn + yn * width;
        magX += image[index] * kernelx[a][b];
    }
 }
Run Code Online (Sandbox Code Playgroud)

请注意,输入是灰度图像,它可以表示为1D的double数组(这只是一个技巧,因为坐标(x,y)中的像素值可以使用index = [x + y*width]来访问)

在给定magX和magY的情况下计算像素(x,y)的大小:

mag = sqrt(magX ^ 2 + magY ^ 2)


kar*_*lip 19

我见过的Sobel算子的最简单的解释来自Saush的博客,一个曾经与Sobel见面的技术爱好者:

在此输入图像描述

该帖子描述了(不是太多)详细说明如何实现过滤器,并分享Ruby源代码用于演示目的:

require 'chunky_png'

class ChunkyPNG::Image
  def at(x,y)
    ChunkyPNG::Color.to_grayscale_bytes(self[x,y]).first
  end
end

img = ChunkyPNG::Image.from_file('engine.png')

sobel_x = [[-1,0,1],
           [-2,0,2],
           [-1,0,1]]

sobel_y = [[-1,-2,-1],
           [0,0,0],
           [1,2,1]]

edge = ChunkyPNG::Image.new(img.width, img.height, ChunkyPNG::Color::TRANSPARENT)

for x in 1..img.width-2
  for y in 1..img.height-2
    pixel_x = (sobel_x[0][0] * img.at(x-1,y-1)) + (sobel_x[0][1] * img.at(x,y-1)) + (sobel_x[0][2] * img.at(x+1,y-1)) +
              (sobel_x[1][0] * img.at(x-1,y))   + (sobel_x[1][1] * img.at(x,y))   + (sobel_x[1][2] * img.at(x+1,y)) +
              (sobel_x[2][0] * img.at(x-1,y+1)) + (sobel_x[2][1] * img.at(x,y+1)) + (sobel_x[2][2] * img.at(x+1,y+1))

    pixel_y = (sobel_y[0][0] * img.at(x-1,y-1)) + (sobel_y[0][1] * img.at(x,y-1)) + (sobel_y[0][2] * img.at(x+1,y-1)) +
              (sobel_y[1][0] * img.at(x-1,y))   + (sobel_y[1][1] * img.at(x,y))   + (sobel_y[1][2] * img.at(x+1,y)) +
              (sobel_y[2][0] * img.at(x-1,y+1)) + (sobel_y[2][1] * img.at(x,y+1)) + (sobel_y[2][2] * img.at(x+1,y+1))

    val = Math.sqrt((pixel_x * pixel_x) + (pixel_y * pixel_y)).ceil
    edge[x,y] = ChunkyPNG::Color.grayscale(val)
  end
end

edge.save('engine_edge.png')
Run Code Online (Sandbox Code Playgroud)

输入/输出:

  • 只是空闲,你已经复制并粘贴了错误的代码(或者在博客文章中它是错误的,现在已经修复了?).sobel_x [0] [4]显然永远不会起作用.它应该是[0] [1] [1] [1] [2] [1]等. (3认同)