Edit Your Old Photos with Machine Learning – Computational Photography

Image Noise Reduction with one of the most powerful noise reduction algorithm


In this article, I will show you how to reduce the noise in your photos using Python programming language. This process is known as Image Noise Reduction. As you may know that the term ‘noise’ is not used only in sound. Noise is also a known term in photography field. Noise can be seen especially when we zoom in too much into the image. Noise reduction can be used to give better look to our old photos. In a noisy image we can see the pixels, and sometimes unwanted details. Reducing the noise gives smoothness to the image.

We all know that the phones were not taking great photos couple years ago. Many phone brands started using this noise reduction technology in their softwares to give better results for the users. This technology is called Computational Photography, you might have heard it in Apple’s October event this year. Our phones can do it, why not build our own. Let’s get to work!

Tablet of Contents:

  • Introduction
  • Step 1 – Libraries
  • Step 2 – Reading Image
  • Step 3 – Non-local Means Denoise Algorithm
  • Final Step – Noise Reduction Function in Action

Introduction

We will be using three packages in this project. Packages are as following: OpenCV, NumPy and Matplotlib. OpenCV is a very well-known computer vision package. We will need Numpy as a prerequisite for OpenCV. When reading an image, we are converting those pixels into arrays, this is happening in the behind scenes. NumPy is great when working with multi-dimensional arrays.

Here is a nice short definition of OpenCV:

OpenCV (Open Source Computer Vision Library) is an open-source computer vision and machine learning software library. OpenCV was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in the commercial products.

Reference: https://opencv.org

Official documentation pages for each package that we will be using in this project. It may a helpful reference when you want resolve a bug or add more features to your program:


Step 1 – Libraries

As mentioned in the introduction, we will need three packages in this project. To be able to use them in our program, first thing first we have to install them. We are going to use PIP, which is a python package manager tool. It makes library installation much faster and efficient. We can install multiples packages in just line, let’s do it:

pip install numpy opencv

Let’s go ahead and create a new Jupiter notebook. Feel free to use your preferred code writing environment. For this project, I will be using Jupyter Notebook. Here is my first block in the notebook, where we are importing the libraries that we just installed.

import numpy as np
import cv2 as cv

Step 2 – Reading Image

In this step, we will find an image that we want to test our program on. It can be a noisy image, or not. Which ever you want to go with. You will still see the difference when testing it with regular photos. Our program is not smart enough to detect if the image is noisy, but a program can be written about that. After choosing an image, copy that into the folder that you are working in. This will make the reading process easier.

Here is the image that choose (renamed as “profile_image.jpg”):

profile_image.jpg

And here is the line to read the image, we are using the imread method by OpenCV:

img = cv.imread('profile_image.jpg')

Each pixel has value. OpenCV’s imread method is going to read and convert the image into a two dimensional array. Let me show you how an image looks like after reading it:

Bonus tip: we can find the size of the image by calculating the array size. Below, we can see that the image I imported is 509 to 680 pixels. Here is how calculate it:


Step 3 – Non-local Means Denoise Algorithm

Here comes the informational part of the project. Firstly, I will share which noise reduction algorithm we will be using. And then, I will share how many parameters it has, and what does each one stands for.

About the algorithm

The yellow circled areas in the image looks similar. And orange circled areas looks similar. The algorithm picks a pixel, takes a small window around it, and then search for a similar windows in the image, average all the windows and replace the pixel with the result it calculated. That’s why it is called non-local, because it doesn’t just check its surrounding, it looks for the whole image.

The function version of this algorithm are as following:

  • fastNlMeansDenoising (for grayscale images).
  • fastNlMeansDenoisingColored (for colored images).

Parameters

fastNlMeansDenoisingColored(src, dst, h, hcolor, templateWindowSize, searchWindowSize)

  • src: the input image that we want to do noise reduction.
  • dst: the destination if we want to export the result.
  • h: the luminance component. (Larger h value removes more noise but can also remove image details).
  • hcolor: the color component. (10 is the recommended value by the documentation for colored images).
  • templateWindowSize: The pixel size of the area that the function will smooth. It should be an odd integer number. (7 is the recommended value by the documentation, which will fit for most cases).
  • searchWindowSize: The pixel size of the area that the function will find and reference to. Affect performance linearly: greater searchWindowsSize means greater denoising time. Also it should be an odd integer number. (21 is the recommended value by the documentation, which will fit for most cases).

Now, let’s see what we just learned in real action.


Final Step – Noise Reduction Function in Action

Perfect! Here comes the fun part of the project. We are going to see how the image will look after noise reduction. We are going to run the function with three different values, this way will be able to see how each effects the final result.

Running the functions

dst1 = cv.fastNlMeansDenoisingColored(img,None,3,3,7,21)
dst2 = cv.fastNlMeansDenoisingColored(img,None,5,5,7,21)
dst3 = cv.fastNlMeansDenoisingColored(img,None,10,10,7,21)
dst4 = cv.fastNlMeansDenoisingColored(img,None,3,3,5,13)

Saving the results as an image using imwrite function

cv.imwrite('one_1.png', dst1)
cv.imwrite('one_2.png', dst2)
cv.imwrite('one_3.png', dst3)
cv.imwrite('one_4.png', dst4)

Results

dst1 vs dst4 comparison (to understand different window pixel sizes):

dst2 vs dst3 comparison (to understand different luminance and color component values):


Conclusion

Congrats! We have built a program that reduces the noise of an image using the non-local means denoising algorithm. It is one of the greatest image noise reduction method to use. There are other denoising algorithms, but they are not powerful as the non-local means denoising algorithm. Some of them are also known as blurring techniques. And as ou can see from the results, we can use this technique to make our photos look like an oil paintings when we add more smoothness. So, it’s all about your imagination.

Working on hands-on programming projects like this one is the best way to sharpen your coding skills. I hope you enjoyed and learned something new today. Feel free to reach me if you have any questions or comments.

Follow my blog and Youtube Channel to stay inspired. Thank you,


More OpenCV projects for you:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s