Histogram of Oriented Gradients

This morning on LinkedIn, NEWSLETTER, Big Technology, A newsletter about Big Tech and society, by Alex Kantrowitz I listened to the podcast Let’s Talk About Temu and Shein, The Fast-Rising, China-Based Retailers Threatening U.S. Mainstays. 

On Big Technology Podcast, Ranjan Roy and Alex Kantrowitz spoke with New York Magazine contributing editor John Herrman about Temu and Shein, the fast-rising, China-based retailers that are threatening the U.S. mainstays including H&M and Amazon.

I have read a few articles and watched a couple videos about Zara.

At the Mall of America Zara and H&M stores are on opposite sides on a hallway on the second level.

I have to admit that I have never purchased items from either store. That said, I have been in both stores in different countries, shopping with my wife.

You can listen on Apple PodcastsSpotify, or your podcast app of choice.

Now let’s get to the main subject of this post which is learning about Histogram of Oriented Gradients (HOG). To read more about the HOG you may do it here.

The HOG is a feature descriptor used for object detection.

# **** folder of interest ****
cd C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos

# **** open file of interest using VSCode ****
(base) C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos>code HistogramOfOrientedGradients.py

# **** execute python script of interest ****
(base) C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos>python HistogramOfOrientedGradients.py

We will start by getting to the folder of interest. You may put the source code for this post in any other folder that is more convenient for you.

Once we get to the folder of interest, we invoke the VSCode IDE which we will use in this post. The author of the course uses the Jupyter notebook instead. At the end of an edit to the Python script, in order to save the changes, you might need to save the script before executing it.

At this point I should disclose that I am a Microsoft employee and have been using VSCode and Visual Studio for several years. With time I have tried to reduce the number of IDEs that I use.

Finally we are ready to execute the Python script.

# **** import statements ****
import matplotlib.pyplot as plt

import skimage
from skimage.feature import hog
from skimage import data, color, io, exposure

As usual we start by adding the libraries of interest. With practice this becomes easier. You can also add them as you go after adding a call to a library not referenced in the import statements.

# **** read image of interest ****
monalisa = skimage.io.imread('./images/pexels-monalisa.jpg')

# **** display image of interest ****
plt.figure(figsize=(10, 8))                         # set the size of the figure
plt.imshow(monalisa, cmap='gray')                   # display image of interest
plt.title('Monalisa')                               # set the title for the image
plt.show()                                          # display the figure

We read in the image of interest. In our case it is the Mona Lisa. Disregarding the beauty of the painting, perhaps the author of the course could have selected a different image with different objects that might be separately identified (i.e., people and cars at an intersection).

The image is then displayed.

# **** compute the HOG of the image ****
fd, hog_image = hog(monalisa,                       # image of interest
                    pixels_per_cell=(16, 16),       # size (in pixels) of a cell
                    block_norm='L2-Hys',            # block normalization method
                    visualize=True,                 # visualize HOG descriptors on image
                    channel_axis=-1)                # axis of color channel in the image

                    #multichannel=True)              # if applying algorithm to a color image


# **** display the HOG of the image ****
fig, axes = plt.subplots(   1,
                            2, 
                            figsize=(10, 8), 
                            sharex=True, 
                            sharey=True)

# **** ****
ax = axes.ravel()                                   # flatten axes array

# **** ****
ax[0].imshow(monalisa, cmap='gray')                 # display image of interest
ax[0].set_title('Original image')                   # set the title for the image

# **** stretch or shrink the intensity levels of the 
#      image- results in a higher contrast image ****
hog_image_rescaled = exposure.rescale_intensity(hog_image,
                                                in_range=(0, 10))

# **** ****
ax[1].imshow(hog_image_rescaled, cmap='gray')       # display HOG of image
ax[1].set_title('HOG image')                        # set the title for the image

# **** ****
plt.tight_layout()                                  # adjust subplot parameters to give specified padding
plt.show()                                          # display the figure

We start by computing the HOG of the image. Note the cell size is set to 16 x 16 pixels.

We perform the necessary steps to display the original image and the HOG image side by side. The image is displayed.

 

# **** compute the HOG of the image (obtain finer features) ****
fd, hog_image = hog(monalisa,                       # image of interest
                    pixels_per_cell=(8, 8),         # was: (16, 16) - size (in pixels) of a cell
                    block_norm='L2-Hys',            # block normalization method
                    visualize=True,                 # visualize HOG descriptors on image
                    channel_axis=-1)                # axis of color channel in the image

# **** display the HOG of the image ****
fig, axes = plt.subplots(   1,
                            2, 
                            figsize=(10, 8), 
                            sharex=True, 
                            sharey=True)

# **** ****
ax = axes.ravel()                                   # flatten axes array

# **** ****
ax[0].imshow(monalisa, cmap='gray')                 # display image of interest
ax[0].set_title('Original image')                   # set the title for the image

# **** stretch or shrink the intensity levels of the 
#      image- results in a higher contrast image ****
hog_image_rescaled = exposure.rescale_intensity(hog_image,
                                                in_range=(0, 10))

# **** ****
ax[1].imshow(hog_image_rescaled, cmap='gray')       # display HOG of image
ax[1].set_title('HOG image')                        # set the title for the image

# **** ****
plt.tight_layout()                                  # adjust subplot parameters to give specified padding
plt.show()                                          # display the figure

Note that this code is the same as in the previous snippet with the only difference on the size of the cell. The size has been reduced in order to provide finer features.

The original and the HOG images are then displayed side by side.

# **** compute the HOG of the image (obtain coarser features) ****
fd, hog_image = hog(monalisa,                       # image of interest
                    pixels_per_cell=(32, 32),       # was: (16, 16) - size (in pixels) of a cell
                    block_norm='L2-Hys',            # block normalization method
                    visualize=True,                 # visualize HOG descriptors on image
                    channel_axis=-1)                # axis of color channel in the image

# **** display the HOG of the image ****
fig, axes = plt.subplots(   1,
                            2, 
                            figsize=(10, 8), 
                            sharex=True, 
                            sharey=True)

# **** ****
ax = axes.ravel()                                   # flatten axes array

# **** ****
ax[0].imshow(monalisa, cmap='gray')                 # display image of interest
ax[0].set_title('Original image')                   # set the title for the image

# **** stretch or shrink the intensity levels of the 
#      image- results in a higher contrast image ****
hog_image_rescaled = exposure.rescale_intensity(hog_image,
                                                in_range=(0, 10))

# **** ****
ax[1].imshow(hog_image_rescaled, cmap='gray')       # display HOG of image
ax[1].set_title('HOG image')                        # set the title for the image

# **** ****
plt.tight_layout()                                  # adjust subplot parameters to give specified padding
plt.show()                                          # display the figure

The code snippet in question is repeated but this time the cell has been set to 32 x 32 in order to provide coarser features.

After generating the HOG image, the original and the HOG image are displayed next to each other.

 

Hope you enjoyed this post. Keep in mind that one of the best ways to learn is to read, experiment, and repeat.

One last thing, the original code for the course has an issue with the current versions of the libraries which I used to generate this post. The issue has been addressed. You can find it by comparing the contents of the Jupyter notebook against the code in this post.

If interested in the code for this post, you may find it in my HistogramOfOrientedGradients repository.

Enjoy,

John

Leave a Reply

Your email address will not be published. Required fields are marked *

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