Friday, November 15, 2024

How do you work with color images in Python?

 Imagine a world without colors, all gray and boring. Imagine flowers, birds, animals devoid of their vibrant hues. It would indeed be a dreary world. Color is at the heart of everyday life and every field you can think of. Consider the blue of the sky, the red of a rose, and the emotions they evoke. The color of walls, matching furniture, and designer curtains all play a crucial role in our surroundings.

The importance of color spans across various activities and applications such as visual communication, aesthetics, brand identity, cognitive impact, and data visualization.

Python libraries we’ve explored (PIL and OpenCV) are robust and user-friendly tools for understanding color in images. They are invaluable in image processing and essential in computer vision.

This post considers the OpenCV library. The python codes are tested using PyCharm. There are more articles on this blog using PyCharm that you may want to look at.


For starters we take a beautiful colored image, The KISS we used earlier and convert it into a gray image. Later on the various other conversions it can make. It just takes a few lines of code. Voila, you have a gray image.

OpenCV's cvtColor() function is very versatile and it can be used to alter the color of the image.

In PyCharm, I create a new project, ColorChanges. It has no color related libraries and you need to install it. If you don't, you will have no such library error.


Installing the OpenCV Library:

You install Opencv-python from PyCharm's Terminal node.



This installs OpenCV as well as Numpy. Opencv-python 4.10.0.84 and numpy 2.1.3 are installed.

The following python code,  UsingOpenCV-_1.py. The PyCharm IDE provides excellent syntax highlighting and color .


Here is the script n text format:

import cv2
# Load the image
image_path = 'path_to_your_image.jpg'
image = cv2.imread(r'C:\Users\hoden\PycharmProjects\exploreImage\Images\TheKiss.jpg')
# Resize the image # You can change the width and height values to #fit your display
width = 738
height = 741
image_resized = cv2.resize(image, (width, height))
# Convert the image from BGR to grayscale
image_gray = cv2.cvtColor(image_resized, cv2.COLOR_BGR2GRAY)
# Save and display the grayscale image
cv2.imwrite('grayscale_image.jpg', image_gray)
cv2.imshow('Grayscale Image', image_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()

Notice that I use an image from another project by giving its absolute path. Also, the original image is pretty big (7380x7410) and if I do not resize, the resulting image after processing will be very large. You can see that cv2.resize() function ressies the image for the new width and height.

Converting color is a breeze with a single line using the function cvtColor().

The last two lines of code are for creating image display window on a keypress event and destroy after the user decides to close all openCV windows.

Here is the result of color conversion:

This is the original image 7380 pixels x 7410 pixels


This is the image after running the python code:










Friday, November 8, 2024

How are PyCharm projects structured?

 The projects created in PyCharm all go into a folder of projects that you can choose.

A new project in PyCharm comes up with two options:

  • Pure Python
  • Django

and opens in the default, Pure Python as shown in the image 

You provide a name for your , by overwriting the default, pythonProject

The location will be the owners folder in C:\Users

Next, it shows the interpreter related information. It creates Project's Venv, the virtual environment in the root of the project and the Python version and its location in the folder structure:

The next picture shows the Python interpreter related details and the version.



The Base conda tabbed page shows the Base conda installed. Conda is another package management and environment management system. 



A brief information about Conda is in the appendix.


The Custom environment tab shows the Type (default is Virtualenv) which is project specific and the location of the python interpreter and its location.

There are options to inherit packages from the base interpreter and also choose to make available the packages to all projects. If you don't choose to make available to all projects then it will be only available for the specific projects. 

When you choose to create a New Project using the Django option you display the following:

To use this option you must upgrade to PyCharm Professional. You also get support for Django templates with many more useful features like syntax and error highlighting, code completion, etc.

The next picture shows the HelloWorld project, a default project that PyCharm is shipped with. The .venv folder has all the packages and the libraries. 

It also has the scripts used in the project as shown:

In order to work with projects, knowing the IDE is very crucial. 








Saturday, November 2, 2024

How do you visualize the histogram of an image?

A picture is worth a thousand words is always true. A one dimensional array does not make a great deal of impact but a visual will do. 

In the previous post on histograms we saw that PIL and OpenCV can be used to provide a 1-dimensional array representing the frequency of each pixel value in the image. We can use the library matplotlib to visualize this array using the following code.

---------------------------

import cv2

import matplotlib.pyplot as plt

image=cv2.imread(r'C:\Users\hoden\PycharmProjects\exploreImage\Images_3\white.png')

histogram = cv2.calcHist([image], [0], None, [256], [0, 256])


# Plot the histogram

plt.plot(histogram)

plt.title('Histogram of an all-white image')

plt.xlabel('Pixel Intensity')

plt.ylabel('Frequency')

plt.show()

------------------------

When we run this code in PyCharm, the a graphic of the Histogram will be displayed. Here is the result of running the above code twice in PyCharm. Matplotlib is pretty flexible and allows us to illustrate the plots with labels.







Friday, November 1, 2024

What is the histogram of an image?

 Histogram is an important quantity in image processing. This post looks at white and black images and their histograms.

Histogram is the distribution of intensities or pixel values. In other words, for a grayscale image, the histogram of the image is the distribution of intensities from 0(black) to 255(white). Each bin in the histogram represents a range of pixel values and the height of the bin indicates the number of pixels that fall within that range. Hence, a uniform gray colored image has just one value for the histogram and one with a gradient has a triangular distribution, and so on.

Python can be used to calculate the histogram of an image. Python uses the libraries related to images like PIL and OpenCV. 

Calculating the histogram [calcHist()] using OpenCV:

At first, let us calculate the histogram of a grayscale image. I have a image all white and let us find its histogram.

using the PyCharm IDE,

histogram = cv2.calcHist([image], [0], None, [256], [0, 256])

[image]: This is a list (or a single image) containing the image to be analyzed. In this case, we are passing a single grayscale image.

[0]: This specifies that we want to calculate the histogram for the first channel of the image. For grayscale images, there is only one channel.

None: This parameter is used for specifying a mask. In this case, we are not using a mask, so we pass None.

[256]: This specifies the number of bins in the histogram. A value of 256 is commonly used for grayscale images, as it corresponds to the possible range of pixel values (0-255).

[0, 256]: This specifies the range of pixel values for which the histogram is calculated. In this case, we are calculating the histogram for all pixel values in the image.

 Note that histogram does not refer to the spatial distribution of the pixel values.

This is the python code for a image all white.

----------------------------------------------

import cv2

image = cv2.imread(r'C:\Users\hoden\PycharmProjects\exploreImage\Images_3\white.png')

histogram = cv2.calcHist([image], [0], None, [256], [0, 256])

print(histogram)

----------------------------------------

 The result is a single array all zeros except the last one. 

[[     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

 [     0.]

.

.

.

.

[636804.]]

  • The intensity value for white pixels is 255.

  • Every pixel in the image has this intensity.

Given these facts, the histogram will show:

  • A peak at the intensity level 255.

  • All other intensity levels (0-254) will have a frequency of 0.

For a perfectly all-black image, the histogram will be,

[[636804.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
 [     0.]
.
.
.
.
.[     0.]
 [     0.]
 [     0.]]

The 636804 being the result of using a 798x798 sized picture

In essence, 

 X-axis: Represents the intensity or brightness level of pixels. In grayscale images, this ranges from 0 (black) to 255 (white).

Y-axis: Represents the number of pixels in the image that have the intensity level corresponding to the x-axis value.

These can be plotted using other image libraries such as matplotlib.

PIL can also be used for calculating the Histogram of an image. Here is the python code.
------------------------------
from PIL import Image

def calculate_histogram(image):
    """Calculates the histogram of an image.

    Args:
        image: A PIL Image object.

    Returns:
        A list containing the pixel counts for each intensity level.
    """

    histogram = image.histogram()
    return histogram

# Load the image
image = Image.open("your_image.jpg")

# Calculate the histogram
histogram = calculate_histogram(image)

# Print the histogram
print(histogram)
-----------------------------------
PIL is a simpler implementation than that of OpenCV. Both the data structure and the visualization are different.  We will look at visualization in future posts.
Histogram are very useful in image recognition related aspects:
  • Image segmentation: Identifying regions of interest within an image based on their pixel intensity distribution.
  • Image enhancement: Adjusting the contrast or brightness of an image based on the histogram.
  • Image comparison: Comparing the histograms of different images to determine their similarity or dissimilarity.

Monday, October 28, 2024

How do you install matplotlib for python?

 

We have seen earlier how to install PIL and OpenCV to visualize images. Matplotlib is yet another library for creating complex plots and graphs.

 Each of these graphic libraries have their own application area:

PIL(Pillow): Great for simple manipulations like cropping, resizing and adding filters. Easy to use but not for extensive visualizations.

OpenCV: Great for real-time computer vision tasks and image processing and lend itself to feature detection, object recognition and video analysis.

Matplotlib: Great for complex plots, graphs,  and charts. Highly customizable.


Installing Matplotlib

Herein, I consider installing matplotlib in the PyCharm IDE that was used for PIL and OpenCV. You can use either the python interpreter to install the library package or the virtual terminal.

In the PyCharm IDE locate the Packages icon highlighted in blue. You can see other packages from earlier installs like pip, pillow, etc. 


In the search box type 'matplotlib' and click Install on the right


There was an error that indicated it is being used. However, it is not installed on this machine in any other program. If this works for you you are in luck.


The virtual terminal is another way to install packages. Locate the Terminal icon in PyCharm. The command line is displayed on the right. 


Type in the following : pip install matplotlib

This should install matplotlib. The program came back saying that it is already present in the site packages. 

------------

(.venv) C:\Users\hoden\OneDrive\Desktop\PyCharm\PIL>pip install matplotlib

Requirement already satisfied: matplotlib in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (3.9.2)Requirement already satisfied: contourpy>=1.0.1 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (1.3.0)Requirement already satisfied: cycler>=0.10 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (0.12.1)Requirement already satisfied: fonttools>=4.22.0 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (4.54.1)Requirement already satisfied: kiwisolver>=1.3.1 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (1.4.7)Requirement already satisfied: numpy>=1.23 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (2.1.1)Requirement already satisfied: packaging>=20.0 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (24.1)Requirement already satisfied: pillow>=8 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (10.4.0)Requirement already satisfied: pyparsing>=2.3.1 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (3.2.0)Requirement already satisfied: python-dateutil>=2.7 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from matplotlib) (2.9.0.post0)  Requirement already satisfied: six>=1.5 in c:\users\hoden\pycharmprojects\exploreimage\.venv\lib\site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)[notice] A new release of pip is available: 23.2.1 -> 24.3.1[notice] To update, run: C:\Users\hoden\PycharmProjects\exploreImage\.venv\Scripts\python.exe -m pip install --upgrade pi

And, indeed it was. The reason for this is perhaps the project files are not in the virtual environment. 

Anyway, before you use matplotlib in your python project, you need to import the plotting routine using 

Import matplotlib.pyplot as plt

Usage of matplotlib 

Python code for displaying an image. 

We will use the same RGB.png image as in the earlier posts.

----------------

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

# Load the image
image = mpimg.imread(r'C:\Users\hoden\PycharmProjects\exploreImage\Images_2\RGB.png')
# Display the image
plt.imshow(image)
plt.axis('off')
# Hide axes for a cleaner look
plt.title('Displayed Image')
plt.show()

----------------

The following image gets displayed:


What display device matplotlib uses to display an image?

Matplotlib uses a backend to display images and plots. The backend is responsible for rendering the visualizations to the screen or saving them to a file. By default, Matplotlib selects the appropriate backend based on your environment. Some common backends are:

  • TkAgg: Uses the Tkinter library for rendering.

  • Qt5Agg: Uses the Qt5 library for rendering.

  • MacOSX: Used for rendering on macOS.

  • GTK3Agg: Uses the GTK3 library for rendering.

  • Agg: Used for rendering to files without displaying on screen.

How to check the display device used for rendering:

The following code is used to check the display device:

Import matplotlib
print(matplotlib.get_backend())

On my Windows 11 laptop, it appears to use the TkAgg library for rendering as I get a reply 'tkagg' for the above code.





Sunday, October 13, 2024

Do these libraries PIL and OpenCV produce exactly the same image, or will there be changes in the rendered images?

 In earlier posts we have seen how images can be displayed using PIL and OpenCV.

Now the question is will these two methods look at the same input image and display the same way?

Here is the chosen image in PNG format, I just created using PAINT. The idea is colors may change, but the text will remain same.

----------------------------------------------------

Using OpenCV

import cv2


# Load the image from file

image = cv2.imread(r'C:\Users\hoden\PycharmProjects\exploreImage\Images_2\RGB.png'

# Display the image in a window

cv2.imshow('Loaded Image', image)

# Wait for a key press and close the window

cv2.waitKey(0)

cv2.destroyAllWindows()

-------------

Using PILLow or PILL

from PIL import Image

# Open an image file

image = Image.open(r'C:\Users\hoden\PycharmProjects\exploreImage\Images_2\RGB.png')

# Display the image

image.show()

---------------------------------------------

The images displayed by the two codes are as shown:



Displayed Image: Using OpenCV
Displayed Image: Using PIl

What I found using PyCharm and a chosen image was that there was no difference. They displayed the same way without any changes to color. The only difference is that the image displayed using OpenCV has a slight cut-off in the left side. This may be corrected by placing the image in the center of a predesigned canvas.

What do the AI assistants say:

However, I decided to quiz the AI tools available on the web Co_Pilot, Gemini and Meta AI.

Gemini's answer:

In most cases, these two methods will display the image with minimal to no noticeable differences. However, there are some potential scenarios where there might be slight variations:

1. Color Space:

OpenCV: By default, OpenCV loads images in BGR (Blue, Green, Red) color space.

Pillow: Pillow loads images based on the image format's native color space (usually RGB for common formats).

This difference is usually negligible for human perception, but it's important to be aware of if you're doing further processing that relies on specific color channels. You can convert the color space in OpenCV using cv2.cvtColor(image, cv2.COLOR_BGR2RGB).

note: Looks like it is not the default behaviour.

2. Alpha Channel Handling:

Images with an alpha channel (transparency information) might be handled slightly differently between the libraries. In most cases, both will display the image with transparency preserved, but there could be subtle differences in how the alpha channel information is interpreted.

3. Advanced Image Formats:

Some uncommon image formats may be supported by one library but not the other, leading to different behavior. However, common formats like JPEG, PNG, and BMP should be handled identically.

In conclusion:

For most display purposes, the two methods will produce visually identical results. However, if you need precise control over color space, alpha channel handling, or are working with uncommon formats, understanding the potential differences between OpenCV and Pillow is important.


Co-Pilot's answer:

The two methods of displaying an image using OpenCV and PIL (Pillow) will not produce exactly the same rendered image due to differences in how each library handles image loading and display. Here are the key differences:

OpenCV

Color Format: OpenCV loads images in BGR format by default. This means that the colors might appear different if you don’t convert the image to RGB before displaying it.

Display Window: OpenCV uses its own windowing system (cv2.imshow) to display images. This window is managed by OpenCV and has its own look and feel.

PIL (Pillow)

Color Format: PIL loads images in RGB format by default. This means that the colors will be displayed as expected without any need for conversion.

Display Method: PIL uses the default image viewer of your operating system to display images (image.show()). This means the image will be displayed in whatever application is set as the default for viewing images on your system.

Summary

Color Handling: OpenCV displays images in BGR format, which can cause color inversion if not converted to RGB. PIL displays images in RGB format.

Display Method: OpenCV uses its own window, while PIL relies on the system’s default image viewer



Meta AI's answer:

Do OpenCV and PIL display the same image in the same way without any color differences?

OpenCV and PIL (Python Imaging Library) handle image display differently, which can result in color differences.

*OpenCV:*


1. Default color space: BGR (Blue, Green, Red)

2. Displays images in BGR format

3. Uses cv2.imshow() function for display


*PIL:*


1. Default color space: RGB (Red, Green, Blue)

2. Displays images in RGB format

3. Uses Image.show() or Image.display() functions

Due to this difference in color spaces:

- Images displayed using OpenCV will have a different color representation compared to PIL.


It is being said that the AI agents greatly help in computer coding. I would say, although they may be working from the same databank of information, they need not provide the same answer. The developer has to know stuff beyond just the codes.

Jump to changing color with Python:

https://hodentekhelp.blogspot.com/2024/11/how-do-you-work-with-color-images-in.html

Wednesday, October 2, 2024

How do I install OpenCV to study images?

 Previously, we have seen how to install OpenCV using PIP.

Now we will see how to work with OpenCV.

In PyCharm, the default python file name is main.py. I already have a main.py and I will create a new python file as shown in the picture. 


When you create a new python file you can give a name to it, main-OpenCV.py herein.

main_opencv.py gets added to the project. The code window on the right is empty and starts at line 1.


Now let us look at the same image as in the previous using PIL.

Run the following code in main-OpenCV as shown.

------------

import cv2

# Load the image from file

image = cv2.imread('Images/TheKiss.jpg')


# Display the image in a window

cv2.imshow('Loaded Image', image)


# Wait for a key press and close the window

cv2.waitKey(0)

cv2.destroyAllWindows()

-----------------------

It takes a short while to generate the image as shown.

You would have noticed the difference between displaying using PIL and OpenCV. The method imshow() is a part of the matplotlib library but has also become a part of the OpenCV.  The imshow() creates a window managed by OpenCV in the context of the OpenCV applications. However the PIL program uses the default viewer settings that can change depending on the settings and the OS.

The images displayed by the two methods can be different as well.

Jump  to installing OpenCV to change color of images: