直方图匹配from skimage.exposure import match_histograms

from skimage.exposure import match_histograms

match_histograms 的实现非常简洁有效。直方图匹配或者直方图规定化

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


def match_histograms(image, reference, *, channel_axis=None):
    """Adjust an image so that its cumulative histogram matches that of another.

    The adjustment is applied separately for each channel.

    Parameters
    ----------
    image : ndarray
        Input image. Can be gray-scale or in color.
    reference : ndarray
        Image to match histogram of. Must have the same number of channels as
        image.
    channel_axis : int or None, optional
        If None, the image is assumed to be a grayscale (single channel) image.
        Otherwise, this parameter indicates which axis of the array corresponds
        to channels.

    Returns
    -------
    matched : ndarray
        Transformed input image.

    Raises
    ------
    ValueError
        Thrown when the number of channels in the input image and the reference
        differ.

    References
    ----------
    .. [1] http://paulbourke.net/miscellaneous/equalisation/

    """
    print(image.ndim, reference.ndim)
    if image.ndim != reference.ndim:
        raise ValueError('Image and reference must have the same number '
                         'of channels.')

    if channel_axis is not None:
        if image.shape[-1] != reference.shape[-1]:
            raise ValueError('Number of channels in the input image and '
                             'reference image must match!')

        matched = np.empty(image.shape, dtype=image.dtype)
        for channel in range(image.shape[-1]):
            matched_channel = _match_cumulative_cdf(image[..., channel],
                                                    reference[..., channel])
            matched[..., channel] = matched_channel
    else:
        # _match_cumulative_cdf will always return float64 due to np.interp
        matched = _match_cumulative_cdf(image, reference)

    # if matched.dtype.kind == 'f':
    #     # output a float32 result when the input is float16 or float32
    #     out_dtype = utils._supported_float_type(image.dtype)
    #     matched = matched.astype(out_dtype, copy=False)
    return matched
def _match_cumulative_cdf(source, template):
    """
    Return modified source array so that the cumulative density function of
    its values matches the cumulative density function of the template.
    """
    print(source.dtype.kind)
    if source.dtype.kind == 'u':
        src_lookup = source.reshape(-1)
        src_counts = np.bincount(src_lookup)
        tmpl_counts = np.bincount(template.reshape(-1))
        print(src_lookup.shape, src_lookup.dtype, src_counts.shape, src_counts.dtype, tmpl_counts.shape, tmpl_counts.dtype)
        print(tmpl_counts.shape)
        # omit values where the count was 0
        tmpl_values = np.nonzero(tmpl_counts)[0]
        tmpl_counts = tmpl_counts[tmpl_values]
        print(tmpl_values.shape, tmpl_counts.shape)
    else:
        src_values, src_lookup, src_counts = np.unique(source.reshape(-1),
                                                       return_inverse=True,
                                                       return_counts=True)
        tmpl_values, tmpl_counts = np.unique(template.reshape(-1),
                                             return_counts=True)

    # calculate normalized quantiles for each array
    src_quantiles = np.cumsum(src_counts) / source.size
    tmpl_quantiles = np.cumsum(tmpl_counts) / template.size
    # 0-255的像素值应该变为多少
    interp_a_values = np.interp(src_quantiles, tmpl_quantiles, tmpl_values)
    return interp_a_values[src_lookup].reshape(source.shape)


if __name__ == "__main__":
    file1 = r'D:\code\3.jpg'
    file2 = r'D:\code\1.jpg'
    img1 = cv2.imread(file1, 0)
    img2 = cv2.imread(file2, 0)
    out = match_histograms(img1, img2)

    plt.figure()
    #plt.imshow(np.hstack((img1, img2, out))[...,::-1]/255)
    plt.imshow(np.hstack((img1, img2, out)), 'gray')
    plt.show()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值