Doi
Doi

Reputation: 157

Denoising a photo with Python

I have the following image which is a scanned copy of an old book. I want to remove the noise in the background (which is a bit reddish) that is coming due to the scanning of the old photo.

enter image description here

Update:

After applying opencv, following the parameter settings in opencv doc, I am getting the following output. enter image description here

Please help fixing this.

The code that I am using:

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, 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,10,7,21)

display_image_in_actual_size(img)
display_image_in_actual_size(dst)

Upvotes: 0

Views: 598

Answers (2)

Bilal
Bilal

Reputation: 3854

The color of some pixels which has near threshold pixel values will be affected, but that depends on the task, here is one solution that you might adjust the threshold to a value that suits your task, also you might remove the median filter, or reduce the sigma value(5) if it affects the text badly, you might have some undesired noise, but the text will be readable.

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()

Upvotes: 1

Lior Cohen
Lior Cohen

Reputation: 5735

opencv library has couple of denoisong functions.

You can find reading with examples here

Upvotes: 1

Related Questions