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

一、定义

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

直方图匹配定义、步骤及代码实现_第1张图片

二、步骤

直方图匹配的步骤如下:

假设原始图像为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),

直方图匹配定义、步骤及代码实现_第2张图片

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

直方图匹配定义、步骤及代码实现_第3张图片

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

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)进行匹配,以此类推,便可得到两张图片灰度级的对应关系,

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

直方图匹配定义、步骤及代码实现_第4张图片

三、代码实现

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)

你可能感兴趣的:(opencv,人工智能,图像处理,python,opencv)