Python 滤除图像中的离群值
Python filter to remove outliers in image
写CNN对图片进行分类。我遇到垃圾像素问题。 image 生成的网络给出了 ~90% 的质量,似乎可以通过对这些像素进行平均来改进它。
numpy、opencv 等中是否有允许执行此操作的现成算法?通常不是平滑,而是专门针对这些像素。还是我必须手动完成?
我同意,如果你使用 CNN 进行某种分类,你应该训练网络来处理这种嘈杂的图像。也许用一些椒盐噪声来扩充你的数据集。无论如何,这是过滤掉异常值的可能解决方案。它建立在 fmw42 提出的想法之上。这些是步骤:
- 使用大内核
应用中值模糊
- 将原始(未处理的)图像转换为灰度
- (Invert) Threshold 具有低阈值(例如,
5
)的灰度图像,为接近 0
的异常值创建掩码.
- 阈值 具有高低阈值(例如
250
)的灰度图像,为接近255
的异常值创建掩码。
- 合并 两个掩码以创建异常值掩码
- 使用离群掩码 adaptive-filter 原始输入图像,必要时替换中值。
让我们看看代码:
# Imports:
import cv2
import numpy as np
# image path
path = "D://opencvImages//noisyNumbers//"
fileName = "noisy01.png"
# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)
# Apply median filter:
filteredImage = cv2.medianBlur(inputImage, ksize=11)
# Convert input image to grayscale:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
内核大小为 11
的中值滤波如下所示:
异常值几乎消失了。现在,让我们暂时搁置这一点,为两个异常值计算一对二进制掩码:
# Get low mask:
_, lowMask = cv2.threshold(grayscaleImage, 5, 255, cv2.THRESH_BINARY_INV)
# Get high mask:
_, highMask = cv2.threshold(grayscaleImage, 250, 255, cv2.THRESH_BINARY)
# Create outliers mask:
outliersMask = cv2.add(lowMask, highMask)
离群掩码是这样的:
现在,你真的不提供你的原始数据。您提供最有可能使用 matplotlib
绘制的图像。这是个问题,因为您发布的图片经过处理和压缩。这会导致原始图像上的异常值周围出现一些锐利的边缘。一种直接的解决方案是稍微扩大异常值掩码以覆盖此压缩伪像:
# Set kernel (structuring element) size:
kernelSize = 3
# Set operation iterations:
opIterations = 1
# Get the structuring element:
maxKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
# Apply dilation:
outliersMask = cv2.dilate(outliersMask, maxKernel)
异常值掩码现在看起来像这样:
好的,让我们 adaptive-filter 使用中值模糊图像和异常值掩码的原始输入。只需确保将所有 numpy
数组重塑为适合广播的大小:
# Re-shape the binary mask to a 3-channeled image:
augmentedBinary = cv2.merge([outliersMask, outliersMask, outliersMask])
# Apply the adaptive filter:
cleanedImage = np.where(augmentedBinary == (255, 255, 255), filteredImage, inputImage)
# Show the result
cv2.imshow("Adaptive Filtering", cleanedImage)
cv2.waitKey(0)
对于第一张图片,这是结果:
更多结果:
写CNN对图片进行分类。我遇到垃圾像素问题。 image 生成的网络给出了 ~90% 的质量,似乎可以通过对这些像素进行平均来改进它。 numpy、opencv 等中是否有允许执行此操作的现成算法?通常不是平滑,而是专门针对这些像素。还是我必须手动完成?
我同意,如果你使用 CNN 进行某种分类,你应该训练网络来处理这种嘈杂的图像。也许用一些椒盐噪声来扩充你的数据集。无论如何,这是过滤掉异常值的可能解决方案。它建立在 fmw42 提出的想法之上。这些是步骤:
- 使用大内核 应用中值模糊
- 将原始(未处理的)图像转换为灰度
- (Invert) Threshold 具有低阈值(例如,
5
)的灰度图像,为接近0
的异常值创建掩码. - 阈值 具有高低阈值(例如
250
)的灰度图像,为接近255
的异常值创建掩码。 - 合并 两个掩码以创建异常值掩码
- 使用离群掩码 adaptive-filter 原始输入图像,必要时替换中值。
让我们看看代码:
# Imports:
import cv2
import numpy as np
# image path
path = "D://opencvImages//noisyNumbers//"
fileName = "noisy01.png"
# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)
# Apply median filter:
filteredImage = cv2.medianBlur(inputImage, ksize=11)
# Convert input image to grayscale:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
内核大小为 11
的中值滤波如下所示:
异常值几乎消失了。现在,让我们暂时搁置这一点,为两个异常值计算一对二进制掩码:
# Get low mask:
_, lowMask = cv2.threshold(grayscaleImage, 5, 255, cv2.THRESH_BINARY_INV)
# Get high mask:
_, highMask = cv2.threshold(grayscaleImage, 250, 255, cv2.THRESH_BINARY)
# Create outliers mask:
outliersMask = cv2.add(lowMask, highMask)
离群掩码是这样的:
现在,你真的不提供你的原始数据。您提供最有可能使用 matplotlib
绘制的图像。这是个问题,因为您发布的图片经过处理和压缩。这会导致原始图像上的异常值周围出现一些锐利的边缘。一种直接的解决方案是稍微扩大异常值掩码以覆盖此压缩伪像:
# Set kernel (structuring element) size:
kernelSize = 3
# Set operation iterations:
opIterations = 1
# Get the structuring element:
maxKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
# Apply dilation:
outliersMask = cv2.dilate(outliersMask, maxKernel)
异常值掩码现在看起来像这样:
好的,让我们 adaptive-filter 使用中值模糊图像和异常值掩码的原始输入。只需确保将所有 numpy
数组重塑为适合广播的大小:
# Re-shape the binary mask to a 3-channeled image:
augmentedBinary = cv2.merge([outliersMask, outliersMask, outliersMask])
# Apply the adaptive filter:
cleanedImage = np.where(augmentedBinary == (255, 255, 255), filteredImage, inputImage)
# Show the result
cv2.imshow("Adaptive Filtering", cleanedImage)
cv2.waitKey(0)
对于第一张图片,这是结果:
更多结果: