直方图匹配

1. 概述

直方图匹配也叫做直方图规定化,是将某个图像的灰度分布按照某个特定的模式去变换的操作。

我们常常用到直方图均衡化,直方图均衡化是在整个灰度阶范围内对图像进行拉升;但是有的时候,这种整个范围内的拉升也许并不是最好的,我们可能会需要其按照某个灰度分布去进行拉升,也就需要用到上面提到的直方图均衡化/规定化。

 

 

2. 步骤

使用到直方图匹配的场景,我们必须知道目的图像,或者目的图像的灰度分布。直方图匹配的步骤如下:

1. 对原始图像进行直方图均衡化:S = T(r)

2.假定对求得的图像,也就是规定化之后的图像进行直方图均衡化:V = G(z)

3. 因为都是进行直方图均衡化,所以有S = V,于是有z = G^{-1}(V) = G^{-1}(S) = G^{-1}(T(r))

 

更具体的:

1. 对原始图像进行直方图均衡化操作有:s_{k} = T(r_{k}) = L*\sum_{i=0}^{i=k}P_{r}(r_{k})

2. 对规定化的图像做直方图均衡化操作有:v_{k} = G(z_{m}) = L*\sum_{j=0}^{j=m}P_{z}(z_{m})

3. 规定化操作的目的就是要找到一个从原始图像到规定化之后图像的映射,积,从r_{k} \rightarrow z_{m}之间的映射关系。

3. 从上面的分析可知:s_{k} = v_{m},有

L*\sum_{i=0}^{i=k}P_{r}(r_{k}) = L*\sum_{i=0}^{j=m}P_{z}(z_{m})

\sum_{i=0}^{i=k}P_{r}(r_{k}) = \sum_{i=0}^{j=m}P_{z}(z_{m})

从公式可以看出,要求出r_{k} \rightarrow z_{m}之间的映射关系,只要满足r_{k}s_{k}的累计概率最相近即可。

 

 

3. 代码

代码步骤:

  1. 计算源图像的累计直方图;
  2. 计算规定图像的累计直方图;
  3. 计算源图像累计直方图各个灰度阶到规定图像的累计直方图各个灰度阶的差的绝对值;
  4. 求出步骤3中各阶中绝对值对应的最小值,最小值对应的灰度阶即为映射后的值。
# coding: utf-8
import cv2
import numpy as np


def show_gray_img_hist(hist, window_title):
    """
    :param hist: 灰度图像的直方图,为一个256*1的 numpy.ndarray
    :return: none
    """
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(hist)
    hist_img = np.zeros([256, 256], np.uint8)
    for h in range(256):
        intensity = int(256 * hist[h] / max_val)
        cv2.line(hist_img, (h, 256), (h, 256 - intensity), [255, 0, 0])

    cv2.imshow(window_title, hist_img)


def get_acc_prob_hist(hist):
    acc_hist = np.zeros([256, 1], np.float32)
    pre_val = 0.
    for i in range(256):
        acc_hist[i, 0] = pre_val + hist[i, 0]
        pre_val = acc_hist[i, 0]

    acc_hist /= pre_val
    return acc_hist


def hist_specify(src_img, dst_img):
    """
    直方图规定化,把dst_img按照src_img的图像进行规定化
    :param src_img:
    :param dst_img:
    :return:
    """
    # 计算源图像和规定化之后图像的累计直方图
    src_hist = cv2.calcHist([src_img], [0], None, [256], [0.0, 255.])
    dst_hist = cv2.calcHist([dst_img], [0], None, [256], [0.0, 255.])
    src_acc_prob_hist = get_acc_prob_hist(src_hist)
    dst_acc_prob_hist = get_acc_prob_hist(dst_hist)

    # 计算源图像的各阶灰度到规定化之后图像各阶灰度的差值的绝对值,得到一个256*256的矩阵,第i行表示源图像的第i阶累计直方图到规定化后图像各
    # 阶灰度累计直方图的差值的绝对值,
    #diff_acc_prob = np.ndarray((256, 256), np.float32)
    #for i in range(256):
    #    for j in range(256):
    #        diff_acc_prob[i, j] = abs(src_acc_prob_hist[i] - dst_acc_prob_hist[j])
    diff_acc_prob = abs(np.tile(src_acc_prob_hist.reshape(256, 1), (1, 256)) - dst_acc_prob_hist.reshape(1, 256))

    # 求出各阶灰度对应的差值的最小值,该最小值对应的灰度阶即为映射之后的灰度阶
    table = np.argmin(diff_acc_prob, axis=0)
    table = table.astype(np.uint8)  # @注意 对于灰度图像cv2.LUT的table必须是uint8类型

    #将源图像按照求出的映射关系做映射
    result = cv2.LUT(dst_img, table)

    # 显示各种图像
    show_gray_img_hist(src_hist, 'src_hist')
    show_gray_img_hist(dst_hist, 'dst_hist')
    cv2.imshow('src_img', src_img)
    cv2.imshow('dst_img', dst_img)
    cv2.imshow('result', result)

    result_hist = cv2.calcHist([result], [0], None, [256], [0.0, 255.])
    show_gray_img_hist(result_hist, 'result_hist')


if __name__ == '__main__':
    src_img = cv2.imread('D:/lena.jpg', 0)
    dst_img = cv2.imread('D:/moon.jpg', 0)

    hist_specify(src_img, dst_img)

    cv2.waitKey()

运行结果如下:

从做到右边分别为模板图像的直方图,原始图像的直方图,模板图像,原始图像,规定化之后的结果,规定化之hi偶的直方图。

 

 

 

 

 

 

  • 24
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Matlab中的直方图匹配是一种图像处理技术,用于将一个图像的直方图与另一个图像的直方图进行匹配,以实现图像增强或图像转换的目的。在Matlab中,可以使用imhist和histeq函数来实现直方图匹配。 具体步骤如下: 1. 首先,使用imread函数读取原始图像和匹配图像。 2. 使用imhist函数计算匹配图像的直方图。 3. 使用histeq函数,将原始图像的直方图与匹配图像的直方图进行匹配,得到匹配后的图像。 4. 使用imshow函数显示原始图像、匹配图像和匹配后的图像。 5. 使用imhist函数分别计算原始图像、匹配图像和匹配后图像的直方图。 6. 使用subplot函数将原始图像、匹配图像和匹配后图像的直方图分别显示在一个图像窗口中。 在Matlab中,可以使用以下代码实现直方图匹配: ```matlab I = imread('lena.bmp'); % 读取原始图像 Imatch = imread('face.bmp'); % 读取匹配图像 Jmatch = imhist(Imatch); % 获取匹配图像的直方图 Iout = histeq(I, Jmatch); % 直方图匹配 % 显示原始图像、匹配图像和匹配后的图像 figure; subplot(1,3,1),imshow(I);title('原图像'); subplot(1,3,2),imshow(Imatch);title('匹配图像'); subplot(1,3,3),imshow(Iout);title('匹配之后图像'); % 显示原始图像、匹配图像和匹配后图像的直方图 figure; subplot(3,1,1),imhist(I,64);title('原图像直方图'); subplot(3,1,2),imhist(Imatch,64);title('匹配图像直方图'); subplot(3,1,3),imhist(Iout,64);title('匹配之后图像直方图'); ``` 这段代码首先使用imread函数读取了原始图像和匹配图像。然后,使用imhist函数计算匹配图像的直方图。接着,使用histeq函数将原始图像的直方图与匹配图像的直方图进行匹配,得到匹配后的图像。最后,使用imshow和imhist函数分别显示原始图像、匹配图像和匹配后图像的直方图。 通过这种方法,我们可以实现图像的直方图匹配,从而改善图像的对比度和细节。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值