Learning how to reduce noises in Images using TensorFlow

Hey there my fellow learners, today let’s talk about how to reduce noise in images using TensorFlow in Python. Let’s Begin!

Introduction to the Problem

One of the fundamental problems in terms of image processing and computer vision is image denoising in which the underlying objective is to approximate the images by noise suppression that is often not possible to prevent in a realistic situation due to various intrinsic or extrinsic conditions. Therefore, denoising images play an important role in various applications such as image restore, visual monitoring, image registration, image segmentation, and image classification where it is necessary to obtain the original image content.

noisy v/s original image

The following flowchart shows how I went along with the Image denoising in the post.

reduce noise - flowchart

Step 1: Importing the necessary modules

First, we import all the required Python libraries:

import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.callbacks import EarlyStopping, LambdaCallback
from tensorflow.keras.utils import to_categorical

Step 2: Data Loading and Preparation

The next step is to load the data and prepare the data for further processing. The data preparation includes:

  1. Reshaping the images
  2. Adding noise to the images

Code for Data Loading

(inp_data,out_data),(inp_test,out_test) = mnist.load_data()
inp_data=inp_data.astype('float')/255.
inp_test=inp_test.astype('float')/255.

Reshaping the Images

inp_data = np.reshape(inp_data, (60000, 784))
inp_test= np.reshape(inp_test,(10000, 784))

Initial Data Visualisation

def Plot_image(x,y):
    plt.figure(figsize=(10,10))
    for i in range(25):
        plt.subplot(5,5,i+1)
        plt.imshow(x[i].reshape(28,28))
        plt.title("Label:" + str(y[i]))
        plt.axis("off")
    plt.show()

The results of plotting the training data are:

train plot

Adding Noise to the training data

noise_train=inp_data + np.random.rand(60000, 784)*0.9
noise_test=inp_test + np.random.rand(10000, 784)*0.9
noise_train=np.clip(noise_train, 0., 1.)
noise_test=np.clip(noise_test, 0., 1.)

The results of plotting data after adding noise to the training data are:

noise train plot

Step 3: Building And Training of a Classifier

Next, I created a Sequential model by passing a list of information about layers:

classifier = Sequential([
    Dense(256, activation = 'relu', input_shape = (784,)),
    Dense(256, activation = 'relu'),
    Dense(256, activation = 'softmax')])

The next step involves compiling the classifier and fitting (training) the training input and output data into the classifier:

classifier.compile(optimizer = 'adam',
                  loss = 'sparse_categorical_crossentropy',
                  metrics = ['accuracy'])
classifier.fit(inp_data,out_data,batch_size = 512, epochs = 3)

Next, I calculated the accuracy of the current classifier on the training as well as the noise added training data:

data_loss,data_accuracy = classifier.evaluate(inp_test,out_test)
print("Training Data: ",data_accuracy*100)
noise_loss,noise_accuracy = classifier.evaluate(noise_test,out_test)
print("Noise added Training Data: ",noise_accuracy*100)

The results of the accuracy of the initial classifier are:

313/313 [==============================] - 0s 737us/step - loss: 0.1276 - accuracy: 0.9612
Training Data:  96.11999988555908
313/313 [==============================] - 0s 738us/step - loss: 10.4048 - accuracy: 0.1813
Noise added Training Data:  18.129999935626984

Step 4: Building and Compiling an Auto-encoder

Autoencoders learn automatically from data examples, which is a useful property as it makes them easy to train so that they will perform well on a specific type of input. Also, it doesn’t require any new engineering, just good and appropriate training data.

Code for building the autoencoder

input_image = Input(shape = (784,))
encoded = Dense(64, activation = 'relu')(input_image)
decoded = Dense(784, activation = 'sigmoid')(encoded)

autoencoder = Model(input_image, decoded)
autoencoder.compile(loss = 'binary_crossentropy', optimizer = 'adam')

Training the autoencoder

autoencoder.fit(
    noise_train, 
    inp_data,
    epochs = 100,
    batch_size = 512,
    validation_split = 0.2,
    verbose = False,
    callbacks = [
        EarlyStopping(monitor = 'val_loss', patience = 5),
        LambdaCallback(on_epoch_end = lambda e,l: print('Loss Calculated: {:.3f}'.format(l['val_loss']), end = '\n'))
    ])
print('\n\n')
print('Training is complete!')

The training shows the result of the loss calculated at each epoch. The output of the first 10 losses are as follows:

Loss Calculated: 0.260
Loss Calculated: 0.225
Loss Calculated: 0.194
Loss Calculated: 0.180
Loss Calculated: 0.172
Loss Calculated: 0.164
Loss Calculated: 0.156
Loss Calculated: 0.150
Loss Calculated: 0.145
Loss Calculated: 0.140

Predicting the denoised images for the testing Data

denoised_images=autoencoder.predict(noise_test)

Visualizing the final denoised Images

The results of plotting the image of noise added testing data is:

noise_test plot

The results of plotting the image of final denoised test images is:

denoised_images plot

Step 5: Checking the final accuracy

Finally, I checked the accuracy of the autoencoder:

test_loss,test_accuracy = classifier.evaluate(denoised_images,out_test)
print("Final Accuracy: ", test_accuracy*100)

The final accuracy of the autoencoder is:

313/313 [==============================] - 0s 742us/step - loss: 0.2097 - accuracy: 0.9342
Final Accuracy:  93.41999888420105

As you can see the final accuracy is 93.42% (over 90%) which is one of the best one can get!

Conclusion

Congratulations! You finally learned to denoise images on your own!

Hope you learned something new! Stay tuned for more!

You can also check out!

Leave a Reply

Your email address will not be published. Required fields are marked *