c# - 图像处理:Sobel 滤镜的结果原来是灰色而不是黑白?
问题描述
我正在尝试自己实现一个 Sobel 过滤器。
我得到的结果看起来和这个非常相似(灰色):
但不是这样(带渐变的黑白):
我曾尝试使用阈值,但感觉不对:
有什么方法可以将灰度转换为带有渐变结果的黑白?
以下是我在 C# 中用于过滤图像的步骤:
- 从文件转换位图(已经灰度)
用 Sobel 核对每个像素进行卷积(例如水平)
私有静态浮点[][] Sobel3x3Kernel_Horizontal() {
return new float[][] { new float[]{ 1, 2, 1}, new float[]{ 0, 0, 0 }, new float[]{ -1, -2, -1} }; }
重新映射所有值,让它们落在0~255的范围内(否则会有负值或大于255的值,不能用来做Bitmap.SetPixel(int x, int y, Color color)
输出位图结果(灰度)
解决方案
要复制您从 Wikipedia 链接的图像,请执行以下步骤:
使用 Sobel 核计算卷积以获得 x 导数
dx
。计算另一个卷积以获得 y 导数
dy
(转置内核)。这两个导数一起形成梯度(每个像素的向量值)。通过计算确定幅度
sqrt(dx^2 + dy^2)
。^2
这里表示正方形。如果您想要纯黑白结果,请对结果设置阈值,否则通过将结果乘以某个值来缩放结果,以便显示的图像对您来说看起来不错。
请注意,您所说的“灰度图像问题”只是将 0 值映射(第三步)到中灰色,因此可以显示负值。这是显示导数的正确方法,否则负值将被剪裁,因此不可见。这些负值是导数的重要组成部分。但是这个映射应该只用于显示,应该总是对原始值进行进一步的计算。