0% found this document useful (0 votes)
88 views

How To Do Histogram Matching Using OpenCV - Automatic Addison

The document describes how to perform histogram matching using OpenCV in Python. It explains that histogram matching transforms an image so that its histogram matches the histogram of a reference image. It provides code to calculate the cumulative distribution functions (CDFs) of the source and reference images, create a lookup table to match the histograms, and transform the source image colors using the lookup table. Applying this to the color channels of the image individually produces the histogram matched output image.

Uploaded by

Zubair
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
88 views

How To Do Histogram Matching Using OpenCV - Automatic Addison

The document describes how to perform histogram matching using OpenCV in Python. It explains that histogram matching transforms an image so that its histogram matches the histogram of a reference image. It provides code to calculate the cumulative distribution functions (CDFs) of the source and reference images, create a lookup table to match the histograms, and transform the source image colors using the lookup table. Applying this to the color channels of the image individually produces the histogram matched output image.

Uploaded by

Zubair
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

Automatic Addison
Build the Future

How to Do Histogram Matching


Using OpenCV

In this tutorial, you will learn how to do histogram matching using OpenCV.
Histogram matching (also known as histogram specification), is the
Sell On TikTok
transformation of an image so that its histogram matches the histogram of an
Open
Reachofnew
image audiences.
your choiceWhat happens
(we’ll on TikTok,
call this image doesn’t stay on
of your TikTok.the
choice TikTok
“reference image”).

https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 1/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

For example, consider this image below.

We want the image above to match the histogram of the reference image below.

Sell On TikTok Open


Reach new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok

https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 2/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

After performing histogram matching, the output image needs to look like this:

Then, to make things interesting, we want to use this mask to mask the output
image.

Sell On TikTok Open


Reach new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok

https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 3/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

Mask

Sell On TikTok Open


Reach new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok

https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 4/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

Masked output image

You Will Need


Anaconda (Python 3.7 or higher)

Directions
Below is the source code for the program that makes everything happen. Make
sure you copy and paste this code into a single Python file (mine is named
histogram_matching.py). Then put that file, as well as your source, reference,
and mask images all in the same directory (or folder) in your computer. Once you
have done that, run the code using the following command (note: mask image is
optional):

python histogram_matching.py <source_image> <ref_image>


[<mask_image>]

For example (put this command all on one line):

python histogram_matching.py aspens_in_fall.jpg forest_resized.jpg


mask.jpg

Source Code

/usr/bin/env python

'
lcome to the Histogram Matching Program!

ven a source image and a reference image, this program


turns a modified version of the source image that matches
e histogram of the reference image.
Sell On TikTok Open
ageReach
Requirements:
new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok
- Source image must be color.
- Reference image must be color.
https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 5/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

- The sizes of the source image and reference image do not


  have to be the same.
- The program supports an optional third image (mask) as
  an argument.
- When the mask image is provided, it will be rescaled to
  be the same size as the source image, and the resulting
  matched image will be masked by the mask image.

age:
python histogram_matching.py <source_image> <ref_image> [<mask_image>]
'

Python 2/3 compatibility


om __future__ import print_function

port cv2 # Import the OpenCV library


port numpy as np # Import Numpy library
port matplotlib.pyplot as plt # Import matplotlib functionality
port sys # Enables the passing of arguments

Project: Histogram Matching Using OpenCV


Author: Addison Sears-Collins
Date created: 9/27/2019
Python version: 3.7

Define the file name of the images


OURCE_IMAGE = "aspens_in_fall.jpg"
FERENCE_IMAGE = "forest_resized.jpg"
ASK_IMAGE = "mask.jpg"
TPUT_IMAGE = "aspens_in_fall_forest_output"
TPUT_MASKED_IMAGE = "aspens_in_fall_forest_output_masked.jpg"

f calculate_cdf(histogram):
  """
  This method calculates the cumulative distribution function
  :param array histogram: The values of the histogram
  :return: normalized_cdf: The normalized cumulative distribution function
  :rtype: array
  """
  # Get the cumulative sum of the elements
  cdf = histogram.cumsum()

  # Normalize the cdf


  normalized_cdf = cdf / float(cdf.max())

  return normalized_cdf

f calculate_lookup(src_cdf, ref_cdf):
  """
  This method creates the lookup table
  :param array src_cdf: The cdf for the source image
  :param array ref_cdf: The cdf for the reference image
  :return: lookup_table: The lookup table
  :rtype: array
  """
Sell On TikTok
  lookup_table = np.zeros(256) Open
  lookup_val = 0 What happens on TikTok, doesn’t stay on TikTok. TikTok
Reach new audiences.
  for src_pixel_val in range(len(src_cdf)):
      lookup_val
https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 6/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

      for ref_pixel_val in range(len(ref_cdf)):


          if ref_cdf[ref_pixel_val] >= src_cdf[src_pixel_val]:
              lookup_val = ref_pixel_val
              break
      lookup_table[src_pixel_val] = lookup_val
  return lookup_table

f match_histograms(src_image, ref_image):
  """
  This method matches the source image histogram to the
  reference signal
  :param image src_image: The original source image
  :param image  ref_image: The reference image
  :return: image_after_matching
  :rtype: image (array)
  """
  # Split the images into the different color channels
  # b means blue, g means green and r means red
  src_b, src_g, src_r = cv2.split(src_image)
  ref_b, ref_g, ref_r = cv2.split(ref_image)

  # Compute the b, g, and r histograms separately


  # The flatten() Numpy method returns a copy of the array c
  # collapsed into one dimension.
  src_hist_blue, bin_0 = np.histogram(src_b.flatten(), 256, [0,256])
  src_hist_green, bin_1 = np.histogram(src_g.flatten(), 256, [0,256])
  src_hist_red, bin_2 = np.histogram(src_r.flatten(), 256, [0,256])   
  ref_hist_blue, bin_3 = np.histogram(ref_b.flatten(), 256, [0,256])   
  ref_hist_green, bin_4 = np.histogram(ref_g.flatten(), 256, [0,256])
  ref_hist_red, bin_5 = np.histogram(ref_r.flatten(), 256, [0,256])

  # Compute the normalized cdf for the source and reference image
  src_cdf_blue = calculate_cdf(src_hist_blue)
  src_cdf_green = calculate_cdf(src_hist_green)
  src_cdf_red = calculate_cdf(src_hist_red)
  ref_cdf_blue = calculate_cdf(ref_hist_blue)
  ref_cdf_green = calculate_cdf(ref_hist_green)
  ref_cdf_red = calculate_cdf(ref_hist_red)

  # Make a separate lookup table for each color


  blue_lookup_table = calculate_lookup(src_cdf_blue, ref_cdf_blue)
  green_lookup_table = calculate_lookup(src_cdf_green, ref_cdf_green)
  red_lookup_table = calculate_lookup(src_cdf_red, ref_cdf_red)

  # Use the lookup function to transform the colors of the original
  # source image
  blue_after_transform = cv2.LUT(src_b, blue_lookup_table)
  green_after_transform = cv2.LUT(src_g, green_lookup_table)
  red_after_transform = cv2.LUT(src_r, red_lookup_table)

  # Put the image back together


  image_after_matching = cv2.merge([
      blue_after_transform, green_after_transform, red_after_transform])
  image_after_matching = cv2.convertScaleAbs(image_after_matching)

Sell Onimage_after_matching
  return TikTok Open
Reach new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok
f mask_image(image, mask):
  """
https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 7/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

  This method overlays a mask on top of an image


  :param image image: The color image that you want to mask
  :param image mask: The mask
  :return: masked_image
  :rtype: image (array)
  """

  # Split the colors into the different color channels


  blue_color, green_color, red_color = cv2.split(image)

  # Resize the mask to be the same size as the source image
  resized_mask = cv2.resize(
      mask, (image.shape[1], image.shape[0]), cv2.INTER_NEAREST)

  # Normalize the mask


  normalized_resized_mask = resized_mask / float(255)

  # Scale the color values


  blue_color = blue_color * normalized_resized_mask
  blue_color = blue_color.astype(int)
  green_color = green_color * normalized_resized_mask
  green_color = green_color.astype(int)
  red_color = red_color * normalized_resized_mask
  red_color = red_color.astype(int)

  # Put the image back together again


  merged_image = cv2.merge([blue_color, green_color, red_color])
  masked_image = cv2.convertScaleAbs(merged_image)
  return masked_image

f main():
  """
  Main method of the program.
  """
  start_the_program = input("Press ENTER to perform histogram matching..."

  # A flag to indicate if the mask image was provided or not by the user
  mask_provided = False

  # Pull system arguments


  try:
      image_src_name = sys.argv[1]
      image_ref_name = sys.argv[2]
  except:
      image_src_name = SOURCE_IMAGE
      image_ref_name = REFERENCE_IMAGE

  try:
      image_mask_name = sys.argv[3]
      mask_provided = True
  except:
      print("\nNote: A mask was not provided.\n")

  # Load the images and store them into a variable


  image_src = cv2.imread(cv2.samples.findFile(image_src_name))
Sell On TikTok
  image_ref = cv2.imread(cv2.samples.findFile(image_ref_name)) Open
Reach new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok
  image_mask = None
  if mask_provided:
https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 8/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

      image_mask = cv2.imread(cv2.samples.findFile(image_mask_name))

  # Check if the images loaded properly


  if image_src is None:
      print('Failed to load source image file:', image_src_name)
      sys.exit(1)
  elif image_ref is None:
      print('Failed to load reference image file:', image_ref_name)
      sys.exit(1)
  else:
      # Do nothing
      pass

  # Convert the image mask to grayscale


  if mask_provided:
      image_mask = cv2.cvtColor(image_mask, cv2.COLOR_BGR2GRAY)
      
  # Calculate the matched image
  output_image = match_histograms(image_src, image_ref)

  # Mask the matched image


  if mask_provided:
      output_masked = mask_image(output_image, image_mask)

  # Save the output images


  cv2.imwrite(OUTPUT_IMAGE, output_image)
  if mask_provided:
      cv2.imwrite(OUTPUT_MASKED_IMAGE, output_masked)
 
  ## Display images, used for debugging
  cv2.imshow('Source Image', image_src)
  cv2.imshow('Reference Image', image_ref)
  cv2.imshow('Output Image', output_image)
  if mask_provided:
      cv2.imshow('Mask', image_mask)
      cv2.imshow('Output Image (Masked)', output_masked)

  cv2.waitKey(0) # Wait for a keyboard event

__name__ == '__main__':
  print(__doc__)
  main()
  cv2.destroyAllWindows()

Sample Output

Sell On TikTok Open


Reach new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok

https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 9/10
7/2/22, 12:49 AM How to Do Histogram Matching Using OpenCV – Automatic Addison

automaticaddison / December 16, 2019 / Computer Vision / image processing, opencv,


python

Automatic Addison /
Proudly powered by WordPress

Sell On TikTok Open


Reach new audiences. What happens on TikTok, doesn’t stay on TikTok. TikTok

https://automaticaddison.com/how-to-do-histogram-matching-using-opencv/ 10/10

You might also like