如何去除图像的噪音?

时间:2018-03-10 13:06:10

标签: ios swift image math filter

目前我正试图摆脱我图像中的所有背景噪音。

我非常确定我必须使用某种扩张侵蚀算法,但我也希望对过滤器例程进行编码在斯威夫特。

这是我未经过滤的嘈杂图像:

unfiltered Image

这可能是应用过滤器后的样子

filtered Image

注意:使用openCV代码应该看起来像(但就像我提到的那样 - 我想要使用Swift)

img = cv2.imread("img.png")
bggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
labelnum, labelimg, contours, GoCs = cv2.connectedComponentsWithStats(bggray)
for label in xrange(1, labelnum):
    x,y,w,h,size = contours[label]
    if size <= 50:
         img[y:y+h, x:x+w] = 0
cv2.imwrite("img.png", img)

注意:这是我到目前为止获得的Swift代码,但显然不是这样的:

class CleanupFilter: CIFilter {
    var inputImage : CIImage?
    var threshold1: Float = 0.5
    var threshold2: Float = 0.7
    var thresholdKernel =  CIColorKernel(source:
        "kernel vec4 thresholdKernel(sampler image, float threshold1, float threshold2) {" +
            "vec4 pixel = sample(image, samplerCoord(image));" +
            "const vec3 rgbToIntensity = vec3(0.114, 0.587, 0.299);" +
            "float intensity = dot(pixel.rgb, rgbToIntensity);" +
            "if (intensity < threshold1) {return vec4(0, 0, 0, 0)}" +
            "if (intensity < threshold1 && intensity > threshold2) {return vec4(1, 1, 1, 1)}" +
            "else {return vec4(0, 0, 0, 0)}" + "}")
    override var outputImage: CIImage! {
        guard let inputImage = inputImage,
            let thresholdKernel = thresholdKernel else {
                return nil
        }
        let extent = inputImage.extent
        let arguments : [Any] = [inputImage, threshold1, threshold2]
        return thresholdKernel.apply(extent: extent, arguments: arguments)
    }
}

非常感谢任何帮助如何编辑 thresholdKernel 以实现有效的过滤程序。

2 个答案:

答案 0 :(得分:2)

尝试一下:

extension UIImage {
    var noiseReducted: UIImage? {
        guard let openGLContext = EAGLContext(api: .openGLES2) else { return self }
        let ciContext = CIContext(eaglContext: openGLContext)

        guard let noiseReduction = CIFilter(name: "CINoiseReduction") else { return self }
        noiseReduction.setValue(CIImage(image: self), forKey: kCIInputImageKey)
        noiseReduction.setValue(0.02, forKey: "inputNoiseLevel")
        noiseReduction.setValue(0.40, forKey: "inputSharpness")

        if let output = noiseReduction.outputImage,
            let cgImage = ciContext.createCGImage(output, from: output.extent) {
            return UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
        }

        return nil
    }
}

答案 1 :(得分:1)

你应该在二值化之前消除噪音,因为你可以看到你的噪音非常大,而且与重要数据的差别很小。这是通过在处理任何FIR滤波器之前模糊您的图像来完成的。

如果你真的需要从像你这样的输入中去除噪音,那么每种方法都有很少的可能性:

  1. 形态运算符

    你可以施加几次侵蚀,这会缩小所有物体。它是可用的如果噪声厚度小于您的对象,那么您的对象仍然停留在那里但是有点粗糙扭曲。在你的情况下,这将只适用于较小的“点”

  2. 细分&amp;阈值

    您可以分割图像上的所有对象并检测/消除噪音。在您的情况下,噪声区域远小于您要保留的对象。因此,计算每个对象的面积(设置像素数)(例如通过填充填充),如果对象的面积小于阈值,则删除它(使用背景颜色填充)。

    你可以阈值任何你想要的属性,如表面积,纵横比,边界框大小,周长与面积比等。这种方法不会扭曲细节,但相当慢,如果没有正确处理递归填充它是更高分辨率的潜在堆栈溢出噩梦。