2026a

# imhistmatch


调整二维图像的直方图以匹配参考图像的直方图

函数库: TyImageProcessing

# 语法

J, = imhistmatch(I,ref)
J, = imhistmatch(I,ref,nbins)
J, = imhistmatch(___;Method=method)
J,hgram = imhistmatch(___)

# 说明

J, = imhistmatch(I,ref) 调整二维灰度或真彩色图像 I 的直方图,使其直方图大致匹配参考图像 ref 的直方图。示例

  • 如果 I 和 ref 都是 RGB 图像,则 imhistmatch 将 I 的每个颜色通道独立匹配到 ref 的相应颜色通道;

  • 如果 I 是 RGB 图像而 ref 是灰度图像,则 imhistmatch 将 I 的每个通道与从 ref 派生的单一直方图进行匹配;

  • 如果 I 是灰度图像,则 ref 也必须是灰度图像。

图像 I 和 ref 不必具有相同的大小。


J, = imhistmatch(I,ref,nbins) 使用 nbins 个均匀间隔的箱子,在给定图像数据类型的适当范围内。返回的图像 J 具有不超过 nbins 个离散级别。

  • 如果图像的数据类型是 Float32 或 Float64,则直方图范围为 [0, 1];

  • 如果图像的数据类型是 UInt8,则直方图范围为 [0, 255];

  • 如果图像的数据类型是 UInt16,则直方图范围为 [0, 65535];

  • 如果图像的数据类型是 Int16,则直方图范围为 [-32768, 32767]。


J, = imhistmatch(___;Method=method) 还指定是否使用均匀或多项式映射技术。示例


J,hgram = imhistmatch(___) 返回用于匹配的参考图像 ref 的直方图 hgram。示例

# 示例

匹配航空图像的直方图

这些航空图像是在不同时间拍摄的,代表了马萨诸塞州康科德同一地形的重叠视图。这个例子演示了输入图像 A 和 Ref 可以具有不同的大小和图像类型。

加载一幅 RGB 图像和一幅参考灰度图像。

using TyImageProcessing
using TyPlot

A = imread("westconcordaerial.png")
Ref = imread("westconcordorthophoto.png")

获取图像 A 的大小。

size(A)
ans = 
(394, 369, 3)

获取图像 Ref 的大小。

size(Ref)
ans = 
(366, 364)

请注意,图像 A 和 Ref 在大小和类型上是不同的。图像 A 是一个真彩色 RGB 图像,而图像 Ref 是一个灰度图像。两个图像的数据类型都是 uint8。

生成直方图匹配的输出图像。该示例将 A 的每个通道与 Ref 的单一直方图进行匹配。输出图像 B 具有图像 A 的特征 - 它是一个 RGB 图像,大小和数据类型与图像 A 相同。图像 B 中每个 RGB 通道的离散级别数量与从灰度图像 Ref 构建的直方图中的箱子数量相同。在这个例子中,Ref 和 B 的直方图具有默认的箱子数量,即 64。

B, = imhistmatch(A, Ref);

显示 RGB 图像 A、参考图像 Ref 和直方图匹配的 RGB 图像 B。在显示之前,对图像进行了调整大小。

imshow(A)
title("RGB Image with Color Cast")
imshow(Ref)
title("Reference Grayscale Image")
imshow(B)
title("Histogram Matched RGB Image")
使用多项式方法进行直方图匹配图像

读取一幅彩色图像和一幅参考图像。为了演示多项式方法,将参考图像指定为两幅图像中较暗的那幅。

using TyImageProcessing
using TyPlot

I = imread("office_4.jpg");
ref = imread("office_2.jpg");
imshowpair(I, ref, "montage")
title("Input Image (Left) vs Reference Image (Right)");

使用多项式方法调整图像 I 的亮度,使其与参考图像 ref 的直方图匹配。为了进行比较,还使用均匀方法调整图像 I 的亮度。

J, = imhistmatch(I, ref; Method="uniform");
K, = imhistmatch(I, ref; Method="uniform");
imshowpair(J, K, "montage")
title("Histogram-Matched Image Using Uniform Method (Left) vs Uniform Method (Right)");

使用均匀方法进行直方图匹配的图像在天空和道路上引入了伪色彩。而使用多项式方法进行直方图匹配的图像则没有出现这种伪影。

匹配 16 位灰度 MRI 图像的直方图

这个例子展示了如何使用不同数量的箱子进行直方图匹配。

加载一幅通过 MRI 采集的膝关节 16 位 DICOM 图像。

using TyImageProcessing
using TyPlot
using TyMath
using TyBase

pkg_dir = pkgdir(TyImageProcessing)
source_path = pkg_dir * "/resources/knee1_dcm.mat"
K = load(source_path)["A"];   # read in original 16-bit image
LevelsK = ty_unique(K[:]);       # determine number of unique code values
println("image K: $(length(LevelsK)) distinct levels");
image K: 448 distinct levels
println("max level =  $(maximum(LevelsK))");
max level =  473
println("min level =  $(minimum(LevelsK))");
min level =  0

所有 448 个离散值都位于低代码值范围内,这导致图像显得较暗。为了解决这个问题,将图像数据缩放到整个 16 位范围 [0, 65535]。

Kdouble = Float64.(K);                  # cast uint16 to double
kmult = 65535 / (maximum(maximum(Kdouble[:]))); # full range multiplier
Ref = UInt16.(ty_round.(kmult * Kdouble));   # full range 16-bit reference image

将参考图像 Ref 变暗,以创建一个可以用于直方图匹配操作的图像 A。

#Build concave bow-shaped curve for darkening |Ref|.
ramp = (0:65535) ./ 65535;
ppconcave = spline([0, 0.1, 0.50, 0.72, 0.87, 1], [0, 0.025, 0.25, 0.5, 0.75, 1]);
Ybuf = ppval(ppconcave, ramp);
Lut16bit = UInt16.(ty_round.(65535 * Ybuf));
# Pass image |Ref| through a lookup table (LUT) to darken the image.
A = intlut(Ref, Lut16bit);

查看参考图像 Ref 和变暗后的图像 A。注意它们具有相同数量的离散代码值,但整体亮度不同。

subplot(1, 2, 1)
imshow(Ref)
title("Ref: Reference Image")
subplot(1, 2, 2)
imshow(A)
title("A: Darkened Image");

使用不同数量的箱子生成直方图匹配的输出图像。首先使用默认的箱子数量 64,然后使用图像 A 中存在的值的数量,即 448 个箱子。

B16bit64, = imhistmatch(A[:,:,1],Ref[:,:,1]);  # default: 64 bins

N = length(LevelsK);     # number of unique 16-bit code values in image A.
B16bitUniq, = imhistmatch(A[:,:,1],Ref[:,:,1],N);

查看这两次直方图匹配操作的结果。

figure()
subplot(1,2,1)
imshow(B16bit64)
title("B16bit64: 64 bins")
subplot(1,2,2)
imshow(Ref)
title("B16bitUniq: $(N) bins")

# 输入参数

I — 输入图像
二维 RGB 图像 | 二维灰度图像

要进行变换的输入图像,可以是二维 RGB 或二维灰度图像。imhistmatch 函数期望数据类型为 Float64 和 Float32 的图像值范围在 [0, 1] 之间。如果输入图像的值超出 [0, 1] 范围,可以将值缩放到预期范围。

数据类型: Float32 | Float64 | Int16 | UInt8 | UInt16

ref — 参考图像
二维 RGB 图像 | 二维灰度图像

作为参考直方图的参考图像,指定为二维 RGB 或二维灰度图像。参考图像提供了均匀分布的 nbins 直方图,输出图像 J 试图匹配该直方图。

imhistmatch 函数期望数据类型为 Float64 和 Float32 的图像值范围在 [0, 1] 之间。

数据类型: Float32 | Float64 | Int16 | UInt8 | UInt16

nbins — 均匀分布的箱子数量
64 (默认) | 正整数

参考直方图中均匀分布的箱子数量,指定为正整数。除了指定图像 ref 中直方图的均匀分布箱子的数量外,nbins 还代表输出图像 J 中存在的离散数据级别的上限。

Method — 映射技术
"uniform" (默认) | "polynomial"

用于将 ref 的直方图映射到图像 I 的映射技术,指定为以下值之一:

  • "uniform" — 使用基于直方图的强度函数和直方图均衡化;

  • "polynomial" — 从源图像和参考图像的累积分布直方图计算立方 Hermite 多项式映射函数。当参考图像比输入图像暗时,这种多项式方法非常有效。在这种情况下,多项式方法比均匀方法提供更平滑的颜色过渡。

# 输出参数

J — 输出图像
二维 RGB 图像 | 二维灰度图像

输出图像,返回为二维 RGB 或二维灰度图像。输出图像来源于图像 I,其直方图与用 nbins 均匀分布的箱子构建的输入图像 ref 的直方图近似匹配。图像 J 的大小和数据类型与输入图像 I 相同。输入参数 nbins 表示图像 J 中包含的离散级别的上限。

数据类型: Float32 | Float64 | Int16 | UInt8 | UInt16

hgram — 从参考图像 ref 导出的直方图计数
1×nbins 向量 | 3×nbins 矩阵

从参考图像 ref 导出的直方图计数,指定为向量或矩阵。当 ref 是真实色彩图像时,hgram 是一个 3 行 nbins 列的矩阵,每一行存储 ref 单个颜色通道的直方图。当 ref 是灰度图像时,hgram 是一个 1 行 nbins 列的向量。

数据类型: Float64