Saturday, November 30, 2024

What are Google style docstrings?

 

If you are working with Python, sooner or later you will encounter the Google Style docstrings.

What are Google style docstrings?

Google docstrings are a special, custom format for documenting Python code based on Google's style guide for documentation. They completely and unambiguously document everything about the python code.

I will keep it simple. Let us say you need to concatenate two strings, "Hello," and " World" that you need to concatenate to produce, "Hello, World".

The python code will be:

====

str1 = "Hello,"

str2 = " World!"

result = str1 + str2

print(result)  # Output: Hello, World!

===========

This good for a simple stuff like this. Perhaps, it is unambiguous to most folks.

How does it look like?


You can appreciate as to how well it has documented. It has definition, arguments, returns neatly documented.

Now what does the Google style docstring looks like when pasted into Notepad, Surprise!

==========

str1 = "Hello"

str2 = " World!"

result = str1 + str2

print(result)  # Output: Hello World!

=====================

Well, Google-style docstrings are not simple text. They are a specific format used to document code in a structured way.

Notepad, as a basic text editor, cannot interpret this format. It simply displays the raw text.

While Notepad may not display the Google Style Docstring(GSD), there are other software

that can:

  • Visual Studio Code: A versatile code editor with excellent support for Python.


  • Atom: A customizable text editor with a focus on simplicity and extensibility.


  • Sublime Text: A powerful text editor with a wide range of plugins for various programming languages.


What is the use of this new rendering of the code and its documentation?

Here are some reasons why it's worth the effort:

  • Enhanced Code Clarity:

Clear and concise docstrings make it easier for others (and future you) to understand the code's intent and usage. Consistent formatting improves code readability and reduces cognitive load.

  • Improved Collaboration:

  • Sharing code with the team:

A shared style guide ensures that all team members are on the same page, leading to smoother collaboration and fewer misunderstandings.

  • Facilitated Code Review:

Clear docstrings make it easier for reviewers to understand the code's logic and identify potential issues.

  • Automated Documentation Generation:

Tools like Sphinx can automatically generate professional-looking documentation from well-formatted docstrings.


 


How are color adjustments made in Python using PIL?

 

 When you adjust color of an image, you are adjusting the color balance which has the following components:

1. White balance: Adjusting color to make it look natural under different lighting conditions. Incandescent lamp, tungsten lamp, etc.

2. Color temperature: Adjusting the warmth or coolness of the image. Higher the temperature (in Kelvin) cooler the image (blue) and cooler the temperature warmer the image (more yellow). It may appear counterintuitive as to how we feel the effects of temperature. In reference to how a black body appears at different Kelvin values, higher Kelvin around 6500K and lower Kelvin, between 2000 to 3000. It represents the hue of a light source.

3. Tint:: adjusting green-magenta balance to correct for any color casts that were not addressed by the above. Note that color casts is an artifact of camera, environment etc. and is unwanted.

Well, in Python using PIL you need to use the ImageEnhance.color() method.

This method just takes a single argument (enhance factor), a floating-point number. The color enhancement for three enhancement factors are as follows:

1.0 : returns a copy of the image

<1.0: decreases the enhancement (e.g., less color)

>1.0: increases the enhancement)e.g., more color)

The PIL library can only do the above corrections or changes but for a more granular control you may need additional libraries or custom software.

Here is an example code and some screenshots. I am again using the "TheKiss" image used earlier. The original image is very large and so I have used a smaller image, about 10% of the original using size adjusting code in the Python code ().

=========================

AdjustColorPIL.py

from PIL import Image, ImageEnhance
from PIL.ImageFile import ImageFile

# Open an image file
image: ImageFile = Image.open(r'C:\Users\hoden\PycharmProjects\exploreImage\Images\TheKiss.jpg')
new_width = image.width // 10
new_height = image.height // 10
image = image.resize((new_width, new_height))
# Create an enhancer object for color
color_enhancer = ImageEnhance.Color(image)
# Enhance the image color with a factor (e.g., 1.5 for 50% more color)
enhanced_image = color_enhancer.enhance(0.5)
# Save the enhanced image
enhanced_image.save("enhanced_0point5.jpg")
# display the image
enhanced_image.show()

===============================

The above code was run for three values of enhance factor 0.5. 1.00 and 1.5. The results are as shown here:

                                            enhance factor= 0.5

                                            enhance factor =1.0 (no enhancement, original)

                                            enhance factor =1.5

The enhancement or otherwise using the enhance factor has no upper or lower limits. But beyond certain values, the result may look weird or uninteresting.

 Here are some practical guidelines:

  • 0.0 ≤ factor < 1.0: This range will reduce color saturation. For example:

    • 0.0: Converts the image to grayscale.

    • 0.5: Significantly reduces color intensity.

  • factor > 1.0: This range will increase color saturation. For example:

    • 1.5: Moderately increases color intensity.

    • 2.0 and above: Can lead to highly saturated, unnatural-looking colors.

Here is the image for enhance factor = 1.85









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.