使用 Python 对照片进行去噪

问题描述

我有以下图片,它是一本旧书的扫描副本。我想去除由于扫描旧照片而出现的背景中的噪点(有点偏红)。

enter image description here

更新:

应用 opencv 后,按照 opencv doc 中的参数设置,我得到以下输出

enter image description here

请帮忙解决这个问题。

我使用的代码

import numpy as np
import cv2
from matplotlib import pyplot as plt

def display_image_in_actual_size(im_data):

    dpi = 80
    height,width,depth = im_data.shape

    # What size does the figure need to be in inches to fit the image?
    figsize = width / float(dpi),height / float(dpi)

    # Create a figure of the right size with one axes that takes up the full figure
    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes([0,1,1])

    # Hide spines,ticks,etc.
    ax.axis('off')

    # display the image.
    ax.imshow(im_data,cmap='gray')

    plt.show()

img = cv2.imread('scan03.jpg')

dst = cv2.fastNlMeansDenoisingColored(img,None,10,7,21)

display_image_in_actual_size(img)
display_image_in_actual_size(dst)

解决方法

opencv 库有几个去噪函数。

您可以找到带有示例的阅读here

,

某些具有接近阈值像素值的像素的颜色会受到影响,但这取决于任务,这是一种解决方案,您可以将阈值调整为适合您任务的值,也可以删除中值滤波器,或者降低 sigma 值(5),如果它严重影响文本,您可能会产生一些不想要的噪音,但文本将是可读的。

result

import numpy as np
import matplotlib.pyplot as plt
import cv2
# Read Image
img = cv2.imread('input.jpg')
# BGR --> RGB
RGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
# BGR --> Gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Set thresholds
th_white = 210
th_black = 85
# copy original gray
mask_white = gray.copy()
mask_black = gray.copy()
# Thresholding
mask_white[mask_white<th_white] = 0
mask_black[mask_black<th_black] = 0
mask_white[mask_white>=th_white] = 255
mask_black[mask_black>=th_black] = 255
# Median Filtering (you can remove if the text is not readable)
median_white = cv2.medianBlur(mask_white,5)
median_black = cv2.medianBlur(mask_black,5)
# Mask 3 channels
mask_white_3 = np.stack([median_white,median_white,median_white],axis=2)
mask_black_3 = np.stack([median_black,median_black,median_black],axis=2)
# Masking the image(in RGB)
result1 = np.maximum(mask_white_3,RGB)
result2 = np.minimum(mask_black_3,result1)
# Visualize the results
plt.imshow(result2)
plt.axis('off')
plt.show()