图像直方图匹配

  当我们谈到图像直方图匹配,我们实际上是在讨论一种图像处理技术,它的目标是将一张图像的像素值分布调整到与另一张图像的像素值分布相匹配。这对于图像处理中的许多任务是有用的,如图像增强、颜色校正等。
原理:
  灰度图像直方图匹配的原理基于直方图变换。每张图像的直方图表示了像素值的分布情况。直方图匹配通过调整图像的像素值,使得两张图像的直方图尽可能相似。这通常涉及到将输入图像的像素值映射到输出图像的像素值,以实现两者之间的分布匹配。
意义:
  直方图匹配可以用来改善图像的对比度、颜色平衡和细节。通过将图像的像素值映射到更合适的范围,可以使图像在视觉上更加吸引人。它也可以用于将图像从一种颜色空间转换到另一种颜色空间,或者用于匹配图像以匹配某种标准。
适用场景:
  1. 图像增强:当图像的对比度较低或细节不明显时,可以使用直方图匹配来增强图像的视觉效果。
  2. 颜色校正:当图像受到光照条件的影响或者摄像设备的色彩偏差时,可以使用直方图匹配来校正颜色。
  3. 风格迁移:在计算机视觉中,可以使用直方图匹配来实现图像的风格迁移,将一个图像的风格应用于另一个图像。
数学表示:
  直方图匹配可以表示为一个像素值的映射函数。假设我们有一个输入图像 I I I和一个目标图像 T T T,我们希望将输入图像的像素值映射到输出图像的像素值。这可以表示为:
O ( x , y ) = round ( T I ⋅ 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)是输出图像中的像素值, I ( x , y ) I(x, y) I(x,y)是输入图像中的像素值, T T T是目标图像的像素值范围。函数 round \text{round} round将结果四舍五入到最近的整数。
示例代码(Python):
  下面是一个使用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)

  上述代码假设输入图像和目标图像都是灰度图像。要在彩色图像上进行直方图匹配,需要对各个颜色通道分别进行处理。在彩色图像上的实现与灰度图像类似,但是需要将操作扩展到每个颜色通道(红色、绿色和蓝色通道)。以下是对彩色图像进行直方图匹配的代码示例:

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)
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
彩色图像直方图匹配是一种用于调整图像颜色分布的技术,它可以使得一张图像的颜色分布与另一张图像的颜色分布相同。在Python中,可以使用OpenCV和NumPy库来实现彩色图像直方图匹配。具体步骤如下: 1. 读取原始图像和目标图像。 2. 将原始图像和目标图像转换为HSV颜色空间。 3. 计算原始图像和目标图像的直方图,并对其进行归一化处理。 4. 计算原始图像和目标图像的累积分布函数(CDF)。 5. 对于原始图像中的每个像素,找到与其最接近的目标图像像素,并将其颜色值赋给原始图像像素。 6. 将调整后的图像转换回RGB颜色空间。 下面是一个简单的Python代码示例,用于实现彩色图像直方图匹配: ``` import cv2 import numpy as np # 读取原始图像和目标图像 img_src = cv2.imread('source_image.jpg') img_target = cv2.imread('target_image.jpg') # 将原始图像和目标图像转换为HSV颜色空间 img_src_hsv = cv2.cvtColor(img_src, cv2.COLOR_BGR2HSV) img_target_hsv = cv2.cvtColor(img_target, cv2.COLOR_BGR2HSV) # 计算原始图像和目标图像的直方图,并对其进行归一化处理 hist_src, bins = np.histogram(img_src_hsv[:,:,0].flatten(), 256, [0,256]) hist_src = hist_src / float(img_src_hsv.shape[0] * img_src_hsv.shape[1]) hist_target, bins = np.histogram(img_target_hsv[:,:,0].flatten(), 256, [0,256]) hist_target = hist_target / float(img_target_hsv.shape[0] * img_target_hsv.shape[1]) # 计算原始图像和目标图像的累积分布函数(CDF) cdf_src = hist_src.cumsum() cdf_target = hist_target.cumsum() # 对于原始图像中的每个像素,找到与其最接近的目标图像像素,并将其颜色值赋给原始图像像素 img_src_hsv[:,:,0] = np.interp(img_src_hsv[:,:,0], bins[:-1], cdf_target*255) # 将调整后的图像转换回RGB颜色空间 img_result = cv2.cvtColor(img_src_hsv, cv2.COLOR_HSV2BGR) # 显示结果图像 cv2.imshow('Result', img_result) cv2.waitKey(0) cv2.destroyAllWindows() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Make_magic

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值