直方图匹配定义、步骤及代码实现

一、定义

直方图匹配又称为直方图规定化,是指将一幅图像的直方图变成规定形状的直方图而进行的图像增强方法,即将某幅影像或某一区域的直方图匹配到另一幅影像上。

二、步骤

直方图匹配的步骤如下:

假设原始图像为img,目标图像为target,则

  1. 求出原图像img的累积直方图img_accu
  2. 求出目标图像target的累积直方图target_accu
  3. 灰度级g在img_accu中对应的值记为img_accu_g,找出target_accu中与img_accu_g最接近的值,记为target_accu_G,记该值对应的灰度级为G
  4. 根据g和G的对应关系,得到img经过匹配之后的直方图

举例说明一下(该示例来源于《https://www.cnblogs.com/picassooo/p/11504937.html》),假设图像总共有3289个像素,把这些像素分成10个灰度级。首先统计两张图像的直方图(左图为img,右图为target),

接着计算两张图片的累积直方图,

接下来统计两张累积直方图中不同灰度级下的像素数量,如,

img_accu_g=[1: 927, 2: 1617, 3: 1252, 4: 2602, 5: 2936, 6: 3157, 7: 3269, 8: 3289, 9: 3289, 10: 3289],

target_accu_G=[1: 0, 2: 0, 3: 20, 4: 132, 5: 353, 6: 687, 7: 1137, 8: 1672, 9: 2362, 10: 3289],

从target_accu_G找出与img_accu_g中的不同灰度级像素个数最接近的灰度级,如,img_accu_g中灰度级为1的像素个数为927,target_accu_G中与这个数值最接近的像素个数是1137,该数值对应的灰度级为7,也就是说img_accu_g中的灰度级1应该与target_accu_G中的灰度级7进行匹配,同理,img_accu_g中的灰度级2(1617)应该与target_accu_G中的灰度级8(1672)进行匹配,以此类推,便可得到两张图片灰度级的对应关系,

得到灰度级的对应关系后,就可进行直方图匹配,

三、代码实现

import cv2
import numpy as np


# BGR转灰度
img = cv2.cvtColor(img_path, cv2.COLOR_BGR2GRAY)
target= cv2.cvtColor(target_path, cv2.COLOR_BGR2GRAY)

# 统计直方图
img_hist = cv2.calcHist([img], [0], None, [256], [0, 256])
target_hist = cv2.calcHist([target], [0], None, [256], [0, 256])

# 统计累积直方图
img_hist_accu = np.cumsum(img_hist, axis=0)
target_hist_accu = np.cumsum(target_hist, axis=0)

# 定义输出图片
out = np.zeros_like(img)

# 将两张图片的灰度级进行匹配
for j in range(256):
    tmp = abs(img_hist_accu[j] - target_hist_accu)
    tmp = tmp.tolist()
    # 找出最接近的灰度级并进行匹配
    out[img[:, :] == j] = tmp.index(min(tmp))

# 保存输出图片
cv2.imwrite(out_path, out)
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
直方图匹配(Histogram Matching)是一种将原图像的直方图映射到给定的目标直方图的方法,从而使新图像的直方图分布类似于目标直方图的过程。在Matlab中,直方图匹配可以通过以下步骤实现: 1. 首先,求给定函数的累积直方图s。 2. 然后,求原图像的累积直方图G。 3. 接着,计算s中每个值在G中距离最小的位置index。 4. 最后,将原图像的每个像素通过index映射到新的像素值。 下面是通过Matlab实现直方图匹配的示例代码: ```matlab clear all; close all; clc; % 定义给定的函数 r = 127; x = -r:r; sigma = 20; y1 = exp(-((x-80).^2)/(2*sigma^2)); y2 = exp(-((x+80).^2)/(2*sigma^2)); y = y1 + y2; % 双峰高斯函数 % 求原图像的直方图 img = imread('lena.jpg'); [m, n = size(img);hist = imhist(img); p = hist / (m * n); % 计算累积直方图 s = zeros(1, 256); for i = 1:256 s(i) = sum(y(1:i)); end % 寻找最近的对应像素值 index = zeros(1, 256); for i = 1:256 tmp = G - s(i); tmp = abs(tmp); [~, index(i)] = min(tmp); end % 映射到新的像素值 imgn = zeros(m, n); for i = 1:m for j = 1:n imgn(i, j) = index(img(i, j) + 1) - 1; % 由原图的灰度通过索引映射到新的灰度 end end imgn = uint8(imgn); % 显示新图像和新图像的直方图 figure; imshow(imgn); figure; plot(imhist(imgn)); ``` 这段代码中,首先定义了给定的函数(双峰高斯函数),然后通过求原图像的直方图和给定函数的累积直方图,找到最近的对应像素值,最后将原图像的每个像素通过索引映射到新的像素值,得到匹配后的新图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chen_znn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值