AppDividend
Latest Code Tutorials

How to Convert RGB Image to Grayscale in Python

To convert RGB image to Grayscale in Python, we have to use the opencv-python package. To get started, we need to import cv2 module, which will make available the functionalities required to read an original image and to convert it to grayscale. We will pass the image through the command line using the argparse module, and then it will convert the image into grayscale.

Convert RGB Image to Grayscale in Python

First, we have to install the opencv-python package. You can install it using the following command.

python3 -m pip install opencv-python

# OR

pip install opencv-python

To convert the RGB image to grayscale, you need to follow the below steps.

  1. Import required modules
  2. Define a Grayscale conversion function
  3. Fetch the input image using the argparse module.

Step 1: Import required modules

We will use the Image object from the PIL module. So we specially import that.

Then import the argparse module. And then import the cv2 module and os module.

# app.py

import argparse
import cv2
import os

Step 2: Define a Grayscale function.

In this function, we will read the image using the cv2.imread() method. 

For simplicity, we assume that the file exists, and everything loads fine, so we will not be doing any error or exception check. Nonetheless, for robust code implementation, you should handle these types of exceptions. Or You will get into trouble.

See the following code.

# Function to convert RGB Image to GrayScale
def convertImageToGray(args):
    image = cv2.imread(args["image"])
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    filename = f"{os.getpid()}.png"
    cv2.imwrite(filename, gray)
    print('The image is converted to Grayscale successfully')

You can see that we have defined a function called convertImageToGray() method.

The function takes args as a parameter. This parameter contains the image we need to convert to grayscale.

As an additional note, which will be necessary for the conversion to grayscale, the imread() function has the channels stored in BGR (Blue, Green, and Red) order by default.

Next, we need to parse the image to grayscale. To do it, we have to call the cvtColor() function, which allows us to convert the image from a color space to another.

As the first input, this function receives the original image. As a second input, it gets the color space conversion code. Since we want to convert the original RGB image from the BGR color space to gray, we use the code COLOR_BGR2GRAY.

Let’s go to the final step.

Step 3: Fetch the input image.

Add the following code inside the app.py file.

# Fetch the arguments from the command line
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
                help="path to input image")
args = vars(ap.parse_args())

Our command-line arguments are parsed. We have the following command-line arguments:

  1. –image: The path to the image we’re sending to the function.

So, when we run the command python3 app.py, we pass the argument path to the image like the following.

python3 app.py --image="data.jpg"

Here, the data.jpg image is passed to the convertImageToGray() method.

Finally, call the function.

So, our final code looks like the following.

import argparse
import cv2
import os

# Function to convert RGB Image to GrayScale
def convertImageToGray(args):
    image = cv2.imread(args["image"])
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    filename = f"{os.getpid()}.png"
    cv2.imwrite(filename, gray)
    print('The image is converted to Grayscale successfully')


# Fetch the arguments from the command line
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
                help="path to input image")
args = vars(ap.parse_args())

# Call the convertImageToGray() Function
filename = convertImageToGray(args)

That is it. Now, go to the terminal and type the following command with the image path.

python3 app.py --image="data.jpg"

You can check your current project folder and look for an image name like 4999.png or any four digits number.png image. Mine image is the right side of the following output.

See the below output.

 

How to Convert RGB Image to Grayscale in Python

Apply threshold to preprocess the image

Until now, at the time of the command, we have passed only one argument called –image.

Now, we will pass another argument, which is called –preprocess whose value is one of the following two.

  1. thresh
  2. blur

We can check to see if we should apply thresholding to preprocess the image, else make a check to see if the median blurring should be done to remove noise.

See the following code.

import argparse
import cv2
import os

# Function to convert Normal Image to GrayScale
def convertImageToGray(args):
    image = cv2.imread(args["image"])
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # check to see if we should apply thresholding to preprocess the image
    if args["preprocess"] == "thresh":
        gray = cv2.threshold(gray, 0, 255,
                             cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

    # check to see if median blurring should be done to remove noise
    elif args["preprocess"] == "blur":
        gray = cv2.medianBlur(gray, 3)

    # write the grayscale image to disk as a temporary file.
    filename = f"{os.getpid()}.png"
    cv2.imwrite(filename, gray)
    print('The image is converted to Grayscale successfully')


# Fetch the arguments from the command line
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
                help="path to input image to be OCR'd")
ap.add_argument("-p", "--preprocess", type=str, default="thresh",
                help="type of preprocessing to be done")
args = vars(ap.parse_args())

# Call the convertImageToGray() Function
filename = convertImageToGray(args)

Now type the following command.

python3 app.py --image="data.jpg" --preprocess="thresh"

Output

 

Convert RGB to graycscale with threshold

Depending on the preprocessing method specified by our command-line argument, we will either threshold or blur the image. This is where you would have to add more advanced preprocessing methods.

The if statement inside the function performs a threshold to segment the foreground from the background. We do this using both the cv2.THRESH_BINARY and cv2.THRESH_OTSU flags.

For details on Otsu’s method, see “Otsu’s Binarization” in the official OpenCV documentation.

Alternatively, a blurring method may be applied. A median blur is applied when the –preprocess flag is set to blur. Applying the median blur can help reduce salt and pepper noise. This kind of filter is useful when it comes to correctly OCR the image using Tesseract.

We can also open both RGB image and Grayscale image programmatically using the cv2 module.

You just have to append the following code inside the function to open both the images.

cv2.imshow('Original image',image)
cv2.imshow('Gray image', gray)
cv2.waitKey(0)
cv2.destroyAllWindows()

To show the images, we have to call the imshow() function of the cv2 module.

The cv2.imshow() function receives as first input a string with the name to assign to the window and as the second argument the image to show.

We will show both images so we can compare the converted image with the original one.

Finally, we will call the waitKey() method, which will wait for a keyboard event.

The waitKey() method receives as input the delay, specified in milliseconds. Nonetheless, if we pass the value 0, then it will wait indefinitely until a key event occurs.

Finally, once the user pressed the key, we call the destroyAllWindows() function, which will destroy the previously created windows.

See the complete code.

import argparse
import cv2
import os

# Function to convert Normal Image to GrayScale
def convertImageToGray(args):
    image = cv2.imread(args["image"])
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # check to see if we should apply thresholding to preprocess the image
    if args["preprocess"] == "thresh":
        gray = cv2.threshold(gray, 0, 255,
                             cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

    # check to see if median blurring should be done to remove noise
    elif args["preprocess"] == "blur":
        gray = cv2.medianBlur(gray, 3)

    # write the grayscale image to disk as a temporary file.
    filename = f"{os.getpid()}.png"
    cv2.imwrite(filename, gray)
    print('The image is converted to Grayscale successfully')
    cv2.imshow('Original image', image)
    cv2.imshow('Gray image', gray)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


# Fetch the arguments from the command line
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
                help="path to input image to be OCR'd")
ap.add_argument("-p", "--preprocess", type=str, default="thresh",
                help="type of preprocessing to be done")
args = vars(ap.parse_args())

# Call the convertImageToGray() Function
filename = convertImageToGray(args)

Now, type the following command.

python3 app.py --image="data.jpg" --preprocess="thresh"

Conclusion

We have created this tutorial for dynamic image conversion. So you can enter whatever path you want to convert that image to grayscale using the argparse module in Python.

That is it for this tutorial.

See also

How to open a file in Python

How to read a file in Python

How to write a file in Python

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.