Reading An Image In Python (Without Using Special Libraries) | by Tanu N Prabhu | Towards Data Science

Well, the above picture is splendid, isn’t it?. It’s a masterpiece to me. Nonetheless, have you ever thought or asked yourself this one million dollar question:
What is an image made up of?
Now, before reading this entire tutorial, I want you guys to answer this question in the comment section, in that way you can give some work to your brain. Anyway, for those of you never answered the question or didn’t know the answer, by reading this article you can finally answer the question with no hesitation. Enough of this hype, let’s get started!. By the way, the entire code for this tutorial can also be found on my GitHub Repository below:
github.com
I was given an assignment in my Image Processing Class (Graduate), where I had to read a raw image from a file resize that image to the specified dimensions using single point re-sampling and weighted average re-sampling algorithms. There was a note given to me saying “Don’t use any external libraries” for your programs especially for reading and saving the image. Only selected algorithms were allowed to use one such in python was numpy. This was very painful to hear, but anyway I had to do it and I did it. In this tutorial, we will only focus on reading and saving the image and nothing fancy.
Write a program that reads a grayscale image in raw format from a file, and save the new image into a new file in raw format. (I just made the question short because this is what you will learn today).
Below is the source for the greyscale 8-bit image. I will be using the 4th sample image “Barbara, 8 bit gray (512 x 512). raw”. The link for other sample images can be found here.
As I said, I will not be using any special libraries of python. Some of the most trending and widely used libraries in the field of Image Processing are:
NumpyOpenCVPILMatplotlib
Numpy
OpenCV
PIL
Matplotlib
The fun part here is just by using OpenCV, PIL, and Matplotlib libraries we can read and save the image to a file in just two lines of code. But the catch here is not to use special libraries and special methods. Numpy is the only standard library that will be used throughout (you will know why).
The moment you all have been waiting for.
The only reason that numpy library is used is to convert the raw image into an array of pixels. Mainly used to store the values in an array.
# Necessary library used for this tutorialimport numpy as np
The dimension of the image is made up of rows and columns.
# For example a particular image in this case would contain (512*512) rows and columns meaning 262,144 pixelsROWS = 512    COLS =  512# Different images have different dimensions. Change it accordingly
# Opening the input image (RAW)fin = open('barbara_gray.raw')     print(fin)
This will prompt the output as:
<_io.TextIOWrapper name='barbara_gray.raw' mode='r' encoding='UTF-8'>
Now, we need to construct a 2D array from the raw data (image). A highly efficient way of reading binary data with a know data-type must be used, this can be done with the help of the numpy library.
This is where the actual fun starts. Thanks to numpy
# Loading the input imageprint("... Load input image")img = np.fromfile(fin, dtype = np.uint8, count = ROWS * COLS)print("Dimension of the old image array: ", img.ndim)print("Size of the old image array: ", img.size)
On executing this you will get
... Load input image Dimension of the old image array:  1 Size of the old image array:  262144
There is one way that we can convert the 1D array to 2D array such as floor dividing the total number of pixels with rows and columns of the image or columns and columns (either is fine). This can be written with the help of a formula :
img = tp // (cols, cols)
tp = total pixels; cols represent rows and columns of the image. The reason we are using floor division rather than division because we need to round off the values as a whole number.
# Conversion from 1D to 2D arrayimg.shape = (img.size // COLS, COLS)print("New dimension of the array:", img.ndim)print("----------------------------------------------------")print(" The 2D array of the original image is: \n", img)print("----------------------------------------------------")print("The shape of the original image array is: ", img.shape)
On executing this you will get
New dimension of the array: 2 ----------------------------------------------------  The 2D array of the original image is:   [[240 240 240 ... 230 230 230]  [240 240 239 ... 230 229 229]  [240 239 238 ... 231 232 232]  ...  [ 50  50  50 ...  50  50  50]  [ 50  50  50 ...  50  50  50]  [ 50  50  50 ...  50  50  50]] ---------------------------------------------------- The shape of the original image array is:  (1000, 1600)
# Save the output imageprint("... Save the output image")img.astype('int8').tofile('NewImage.raw')print("... File successfully saved")# Closing the filefin.close()
This is how you save the new image in a raw format. This will be saved in your local system.
... Save the output image ... File successfully saved
Note: While entering the rows and columns of the image. For example if the resolution of an image is 1600x1000, then it means the width is 1600 and the height is 1000. Similarly in the above program the rows would be 1000 and the columns would be 1600.
On successfully executing the above code you are now able to read the raw image, and then save the raw image. Yay!!!. Now if you don’t believe me you can open the saved image using some online image opener tool (or whatever). I normally use photopea, and this is what I get.
Just a heads up, above is the screenshot of the output along with the tool, the main output image is the greyscale called “Barbara” (a woman who has her one hand raised or whatever).
Before leaving, try reading images with other formats such as JPEG (JPG), PNG, and see what values you get. Also, try reading a color (RGB) image. Anyway, now you can easily answer the above question at the beginning of the tutorial. Let me remind you again. “What is the image made up of?”. The answer is as you all saw, “The image is made up of an array of pixel values”. The number of values depends on the rows and columns of the given image.
That’s all it for today, I hope you guys enjoyed reading the tutorial “Reading An Image In Python (Without Using Special Libraries)”. As promised I did not use any other libraries apart from numpy. Well, duh! you need to use numpy to handle arrays. If you guys have any comments or concerns about the tutorial, then let me know in the comment section below. Until then goodbye, stay safe:)