Image histogram matching

  When we talk about image histogram matching, we are actually talking about an image processing technique whose goal is to adjust the distribution of pixel values ​​in one image to match the distribution of pixel values ​​in another image. This is useful for many tasks in image processing, such as image enhancement, color correction, etc.
Principle:
  The principle of grayscale image histogram matching is based on histogram transformation. The histogram of each image represents the distribution of pixel values. Histogram matching adjusts the pixel values ​​of the images to make the histograms of the two images as similar as possible. This usually involves mapping the pixel values ​​of the input image to the pixel values ​​of the output image to achieve a distribution match between the two.
Significance:
  Histogram matching can be used to improve image contrast, color balance, and detail. You can make an image more visually appealing by mapping its pixel values ​​to a more appropriate range. It can also be used to convert images from one color space to another, or to match images to match some standard.
Applicable scenarios:
  1. Image enhancement: When the contrast of the image is low or the details are not obvious, histogram matching can be used to enhance the visual effect of the image.
  2. Color correction: When the image is affected by lighting conditions or color deviation of the camera equipment, histogram matching can be used to correct the color.
  3. Style transfer: In computer vision, histogram matching can be used to achieve image style transfer, and the style of one image is applied to another image.
Mathematical representation:
  Histogram matching can be expressed as a mapping function of pixel values. Suppose we have an input image III and a target imageTTT , we wish to map the pixel values ​​of the input image to the pixel values ​​of the output image. This can be expressed as:
O ( x , y ) = round ( TI ⋅ I ( x , y ) ) O(x, y) = \text{round}\left(\frac{T}{I} \cdot I( x, y)\right)O(x,y)=round(ITI(x,y ) )
  ,O ( x , y ) O(x, y)O(x,y ) is the pixel value in the output image,I ( x , y ) I(x, y)I(x,y ) is the pixel value in the input image,TTT is the pixel value range of the target image. Functionround \text{round}round rounds the result to the nearest integer.
Sample code (Python):
  Here is a sample code for grayscale image histogram matching using OpenCV:

import cv2
import numpy as np

def HistMatch(input_image,target_image):
    input_image=cv2.imread(input_image,flags=0)
    target_image=cv2.imread(target_image,flags=0)

    if input_image is None or target_image is None:
        print('Unable to load input_image or target_image!')
        return
    else:
        # 计算输入图像和目标图像的直方图
        input_hist = cv2.calcHist([input_image], [0], None, [256], [0, 256])
        target_hist = cv2.calcHist([target_image], [0], None, [256], [0, 256])
        # 归一化直方图
        input_hist /= input_hist.sum()
        target_hist /= target_hist.sum()
        # 计算累积分布函数(CDF)
        input_cdf = input_hist.cumsum()
        target_cdf = target_hist.cumsum()
        # 计算映射函数
        mapping = np.interp(input_cdf, target_cdf, np.arange(256))
        # 将映射应用于输入图像
        output_image = mapping[input_image]
        # 转换回8位图像
        output_image = np.uint8(output_image)

        # 显示图像
        cv2.imshow('input_image', input_image)
        cv2.imshow('target_image', target_image)
        cv2.imshow('output_image', output_image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

imgfile1='./Images/cat.jpg'
imgfile2='./Images/Atest1.jpg'
HistMatch(imgfile1,imgfile2)

  The above code assumes that both the input image and the target image are grayscale images. To perform histogram matching on color images, each color channel needs to be processed separately. Implementation on color images is similar to grayscale images, but requires extending the operation to each color channel (red, green, and blue channels). The following is a code example for histogram matching on color images:

import cv2
import numpy as np
import matplotlib.pyplot as plt

def HistMatch(input_image,target_image):
    input_image=cv2.imread(input_image)
    target_image=cv2.imread(target_image)

    if input_image is None or target_image is None:
        print('Unable to load input_image or target_image!')
        return
    else:
        #先将输入图像和目标图像的通道进行分离
        input_channels=cv2.split(input_image)
        target_channels=cv2.split(target_image)
        # print(input_channels)

        output_channels=[]

        # zip 函数将每个输入可迭代对象中相同位置的元素组合在一起,生成一个新的元组,然后将这些元组组合成一个新的可迭代对象。
        for input_channel,target_channel in zip(input_channels,target_channels):

            # 计算输入图像和目标图像的直方图
            input_hist = cv2.calcHist([input_channel], [0], None, [256], [0, 256])
            target_hist = cv2.calcHist([target_channel], [0], None, [256], [0, 256])

            # 归一化直方图
            input_hist /= input_hist.sum()
            target_hist /= target_hist.sum()

            # 计算累积分布函数(CDF)
            input_cdf = input_hist.cumsum()
            target_cdf = target_hist.cumsum()

            # 计算映射函数
            mapping = np.interp(input_cdf, target_cdf, np.arange(256))

            # 将映射应用于输入通道
            output_channel = mapping[input_channel]

            # 转换回8位图像
            output_channel = np.uint8(output_channel)

            output_channels.append(output_channel)

        # 获得通道以获得输出图像
        output_image=cv2.merge(output_channels)

        plt.figure(figsize=(10, 7))
        plt.subplot(231), plt.title("Original image"), plt.axis('off')
        plt.imshow(cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB))  # 显示原始图像

        plt.subplot(232), plt.title("Matching template"), plt.axis('off')
        plt.imshow(cv2.cvtColor(target_image, cv2.COLOR_BGR2RGB))  # 显示匹配模板

        plt.subplot(233), plt.title("Matching output"), plt.axis('off')
        plt.imshow(cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB))  # 显示匹配结果

        histImg, bins = np.histogram(input_image.flatten(), 256)  # 计算原始图像直方图
        plt.subplot(234, yticks=[]), plt.bar(bins[:-1], histImg)

        histRef, bins = np.histogram(target_image.flatten(), 256)  # 计算匹配模板直方图
        plt.subplot(235, yticks=[]), plt.bar(bins[:-1], histRef)

        histOut, bins = np.histogram(output_image.flatten(), 256)  # 计算匹配结果直方图
        plt.subplot(236, yticks=[]), plt.bar(bins[:-1], histOut)

        plt.show()



imgfile1='./Images/cat.jpg'
imgfile2='./Images/Atest1.jpg'
HistMatch(imgfile1,imgfile2)

Guess you like

Origin blog.csdn.net/qq_50993557/article/details/132462797