📜  与 OpenCV、scikit-image 和Python匹配的直方图

📅  最后修改于: 2022-05-13 01:54:57.517000             🧑  作者: Mango

与 OpenCV、scikit-image 和Python匹配的直方图

直方图匹配用于规范化图像的表示,它可以用于特征匹配,特别是当图片来自不同来源或在不同条件下(取决于光线等)。每个图像都有多个通道,每个通道单独匹配。只有当输入图像和参考图像中的通道数匹配时,才能进行直方图匹配。

直方图匹配的主要目标是:

  • 对于每个图像,我们需要创建直方图。
  • 看一下参考图像的直方图。
  • 使用参考直方图,更新输入图片中的像素强度值,使其匹配。

match_histograms() 方法:

该方法用于修改一张图片的累积直方图以匹配另一张图片的直方图。对于每个通道,单独进行修改。

示例 1:使用 OpenCV 和 scikit-image。

代码首先导入必要的包,使用 OpenCV 的 imread() 方法读取图像,然后我们检查输入图像和参考图像的通道数,如果它们不匹配,我们将无法执行直方图匹配。 match_histograms 用于查找匹配的图像。为每个通道绘制直方图。

Python3
# import packages
import matplotlib.pyplot as plt
from skimage import exposure
from skimage.exposure import match_histograms
import cv2
  
# reading main image
img1 = cv2.imread("img.jpeg")
  
# checking the number of channels
print('No of Channel is: ' + str(img1.ndim))
  
# reading reference image
img2 = cv2.imread("2Fw13.jpeg")
  
# checking the number of channels
print('No of Channel is: ' + str(img2.ndim))
  
image = img1
reference = img2
  
matched = match_histograms(image, reference ,
                           multichannel=True)
  
  
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, 
                                    figsize=(8, 3),
                                    sharex=True, sharey=True)
  
for aa in (ax1, ax2, ax3):
    aa.set_axis_off()
  
ax1.imshow(image)
ax1.set_title('Source')
ax2.imshow(reference)
ax2.set_title('Reference')
ax3.imshow(matched)
ax3.set_title('Matched')
  
plt.tight_layout()
plt.show()
  
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8))
  
for i, img in enumerate((image, reference, matched)):
    for c, c_color in enumerate(('red', 'green', 'blue')):
        img_hist, bins = exposure.histogram(img[..., c], 
                                            source_range='dtype')
        axes[c, i].plot(bins, img_hist / img_hist.max())
        img_cdf, bins = exposure.cumulative_distribution(img[..., c])
        axes[c, i].plot(bins, img_cdf)
        axes[c, 0].set_ylabel(c_color)
  
axes[0, 0].set_title('Source')
axes[0, 1].set_title('Reference')
axes[0, 2].set_title('Matched')
  
plt.tight_layout()
plt.show()


Python3
# importing packages
import matplotlib.pyplot as plt
from skimage import data
from skimage import exposure
from skimage.exposure import match_histograms
  
# loading data
reference = data.moon()
image = data.camera()
  
# matching histograms
matched = match_histograms(image, reference, 
                           multichannel=True,)
  
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, 
                                    ncols=3, 
                                    figsize=(8, 3),
                                    sharex=True, 
                                    sharey=True)
for aa in (ax1, ax2, ax3):
    aa.set_axis_off()
  
# displaying images
ax1.imshow(image)
ax1.set_title('Source image')
ax2.imshow(reference)
ax2.set_title('Reference image')
ax3.imshow(matched)
ax3.set_title('Matched image')
  
plt.tight_layout()
plt.show()


Python3
# displaying histograms.
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8))
  
for i, img in enumerate((image, reference, matched)):
    for c, c_color in enumerate(('red', 'green', 'blue')):
        img_hist, bins = exposure.histogram(img[..., c],
                                            source_range='dtype')
        axes[c, i].plot(bins, img_hist / img_hist.max())
        img_cdf, bins = exposure.cumulative_distribution(img[..., c])
        axes[c, i].plot(bins, img_cdf)
        axes[c, 0].set_ylabel(c_color)
  
axes[0, 0].set_title('Source image')
axes[0, 1].set_title('Reference image')
axes[0, 2].set_title('Matched image')
  
plt.tight_layout()
plt.show()


输出:

示例 2:仅使用 scikit-image:

这个例子与前面的例子类似,只是我们从 skimage.data 包中加载图像。然后我们匹配直方图,显示图像,绘制直方图。

Python3

# importing packages
import matplotlib.pyplot as plt
from skimage import data
from skimage import exposure
from skimage.exposure import match_histograms
  
# loading data
reference = data.moon()
image = data.camera()
  
# matching histograms
matched = match_histograms(image, reference, 
                           multichannel=True,)
  
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, 
                                    ncols=3, 
                                    figsize=(8, 3),
                                    sharex=True, 
                                    sharey=True)
for aa in (ax1, ax2, ax3):
    aa.set_axis_off()
  
# displaying images
ax1.imshow(image)
ax1.set_title('Source image')
ax2.imshow(reference)
ax2.set_title('Reference image')
ax3.imshow(matched)
ax3.set_title('Matched image')
  
plt.tight_layout()
plt.show()

输出”

显示上述图像的直方图。

Python3

# displaying histograms.
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8))
  
for i, img in enumerate((image, reference, matched)):
    for c, c_color in enumerate(('red', 'green', 'blue')):
        img_hist, bins = exposure.histogram(img[..., c],
                                            source_range='dtype')
        axes[c, i].plot(bins, img_hist / img_hist.max())
        img_cdf, bins = exposure.cumulative_distribution(img[..., c])
        axes[c, i].plot(bins, img_cdf)
        axes[c, 0].set_ylabel(c_color)
  
axes[0, 0].set_title('Source image')
axes[0, 1].set_title('Reference image')
axes[0, 2].set_title('Matched image')
  
plt.tight_layout()
plt.show()

输出: