Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 图像处理:Sobel滤波器的结果是灰色而不是黑白?_C#_Image Processing_Sobel - Fatal编程技术网

C# 图像处理:Sobel滤波器的结果是灰色而不是黑白?

C# 图像处理:Sobel滤波器的结果是灰色而不是黑白?,c#,image-processing,sobel,C#,Image Processing,Sobel,我正在尝试自己实现一个Sobel过滤器 我得到的结果与此非常相似(灰色): 但不是这样(黑白渐变): 我尝试过使用阈值,但感觉不太对劲: 是否有任何方法可以将灰度转换为带有梯度的黑白 以下是我在C#中过滤图像的步骤: 从文件(已为灰度)转换位图 使用Sobel内核对每个像素进行卷积(例如水平) private static float[][] Sobel3x3Kernel_Horizontal() { return new float[][] { new flo

我正在尝试自己实现一个Sobel过滤器

我得到的结果与此非常相似(灰色):

但不是这样(黑白渐变):

我尝试过使用阈值,但感觉不太对劲:

是否有任何方法可以将灰度转换为带有梯度的黑白


以下是我在C#中过滤图像的步骤:

  • 从文件(已为灰度)转换位图
  • 使用Sobel内核对每个像素进行卷积(例如水平) private static float[][] Sobel3x3Kernel_Horizontal() {

        return new float[][] {
            new float[]{ 1, 2, 1},
            new float[]{ 0, 0, 0 },
            new float[]{ -1, -2, -1}
        };
    
    }
    

  • 重新映射所有值,使其在0~255范围内(否则将出现负值或大于255的值,无法用于执行位图。SetPixel(int x,int y,Color Color)

  • 输出位图结果(灰度)


  • 要复制从Wikipedia链接的图像,请执行以下步骤:

  • 使用Sobel核计算卷积以获得x导数
    dx

  • 计算另一个卷积以获得y导数
    dy
    (转置内核)

  • 这两个导数一起形成梯度(每个像素的矢量值)。通过计算
    sqrt(dx^2+dy^2)
    ^2
    确定大小,此处表示平方

  • 如果希望得到纯黑白结果,请设置结果阈值,否则,通过将结果乘以某个值来缩放结果,以便显示的图像看起来很好


  • 请注意,您所谓的“灰度图像问题”只是映射(您的第三步)将0值转换为中间灰色,以便显示负值。这是显示导数的正确方法,否则负值将被剪裁,因此不可见。这些负值是导数的重要组成部分。但此映射应仅用于显示,应始终对n原始值。

    将所有负值设置为零。请参见示例,谢谢您的回答!但是,在执行(步骤3.)之前,“重新映射”步骤,卷积后获得的像素值在-565~616范围内。我可以将所有负值设置为零,但是我可以如何处理那些大于0的值以获得具有梯度结果的黑白图像?如果像
    if(pixel>255){pixel=255;}else如果(pixel<0){pixel=0;},只需一个
    再次感谢…不幸的是,我照你说的做了,但是结果仍然是一样的(灰度)…第一张图片中的这行代码有什么问题吗?c=Color.FromArgb(255,value,value,value);非常感谢你回答我的问题!在你第三步之后,我得到了震级,我设置了一个if-else语句(不是x-gradient,也不是y-gradient,而是震级)
    if(震级>255){magnet=255;}else if(震级<0){magnet=0;}
    放弃负值和大于255的值,现在我终于有了一个奇妙的结果!我希望我的if-else语句在这里调整幅度范围是合适的。所以这是我的第三步(重新映射)这会导致灰度图像问题…否则,就像你说的,梯度大小图像原本应该是黑白的。导数有负值,梯度大小没有。你可以将梯度大小图像乘以
    255/max
    ,其中
    max
    是最大值。你可以也可以在你正在做的时候剪辑,但是你会丢失信息。你称之为“灰度图像问题”只是将0值映射到中灰色,以便显示负值。这是完全有效的,但仅用于显示,应始终对原始值进行进一步计算,而不是缩放值。当我将结果与Wikipedia中的图像进行比较时,我得出结论,您没有正确计算大小。请确保e取两个分量的平方和,而不是直接取它们的和。你应该看不到负值,砖块的所有4个边都应该有相同的响应-在你的结果中,只有右边缘和下边缘有响应,其他两个可能有负响应,你将其设置为零。或者你可能正在丢弃负值es在
    dx
    dy
    中。不要这样做。将它们存储在有符号整数类型(或浮点类型)数组中