Python 图像处理介绍--彩色图像的直方图处理

技术讨论 黑人 ⋅ 于 3个月前 ⋅ 570 阅读
来源:小白学视觉

在昨天的文章中我们介绍了基于灰度图像的直方图处理,也简单的提到了彩色图像的直方图处理,但是没有讨论最好的方法。

让我们从导入所有需要的库开始吧!

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
import matplotlib.pyplot as plt
from skimage.exposure import histogram, cumulative_distribution
from scipy.stats import norm
现在让我们载入图像。

dark_image = imread('dark_books.png');

dark_image = imread('dark_books.png');
plt.figure(num=None, figsize=(8, 6), dpi=80)
imshow(dark_image);

file

为了帮助我们更好地了解此图像中的 RGB 图层,让我们隔离每个单独的通道。

def rgb_splitter(image):

def rgb_splitter(image):
rgb_list = ['Reds','Greens','Blues']
fig, ax = plt.subplots(1, 3, figsize=(17,7), sharey = True)
for i in range(3):
ax[i].imshow(image[:,:,i], cmap = rgb_list[i])
ax[i].set_title(rgb_list[i], fontsize = 22)
ax[i].axis('off')
fig.tight_layout()
rgb_splitter(dark_image)

file

现在我们已经对单个颜色通道有了大致的了解,现在查看它们的CDF。

def df_plotter(image):

def df_plotter(image):
freq_bins = [cumulative_distribution(image[:,:,i]) for i in
range(3)]
target_bins = np.arange(255)
target_freq = np.linspace(0, 1, len(target_bins))
names = ['Red', 'Green', 'Blue']
line_color = ['red','green','blue']
f_size = 20

fig, ax = plt.subplots(1, 3, figsize=(17,5))
for n, ax in enumerate(ax.flatten()):
    ax.set_title(f'{names[n]}', fontsize = f_size)
    ax.step(freq_bins[n][1], freq_bins[n][0], c=line_color[n],
            label='Actual CDF')
    ax.plot(target_bins, 
         target_freq, 
         c='gray', 
         label='Target CDF',
         linestyle = '--')

df_plotter(dark_image)

file

正如我们所看到的,这三个通道都离理想化的直线相当远。为了解决这个问题,让我们简单地对其CDF进行插值。

def rgb_adjuster_lin(image):

def rgb_adjuster_lin(image):

target_bins = np.arange(255)
target_freq = np.linspace(0, 1, len(target_bins))
freq_bins = [cumulative_distribution(image[:,:,i]) for i in 
             range(3)]
names = ['Reds', 'Blues', 'Greens']
line_color = ['red','green','blue']
adjusted_figures = []
f_size = 20

fig, ax = plt.subplots(1,3, figsize=[15,5])
for n, ax in enumerate(ax.flatten()):
    interpolation = np.interp(freq_bins[n][0], target_freq, 
                              target_bins)
    adjusted_image = img_as_ubyte(interpolation[image[:,:, 
                                  n]].astype(int))
    ax.set_title(f'{names[n]}', fontsize = f_size)
    ax.imshow(adjusted_image, cmap = names[n])
    adjusted_figures.append([adjusted_image])
fig.tight_layout()
fig, ax = plt.subplots(1,3, figsize=[15,5])
for n, ax in enumerate(ax.flatten()):
    interpolation = np.interp(freq_bins[n][0], target_freq, 
                              target_bins)
    adjusted_image = img_as_ubyte(interpolation[image[:,:, 
                                  n]].astype(int))
    freq_adj, bins_adj = cumulative_distribution(adjusted_image)

    ax.set_title(f'{names[n]}', fontsize = f_size)
    ax.step(bins_adj, freq_adj, c=line_color[n], label='Actual 
            CDF')
    ax.plot(target_bins, 
            target_freq, 
            c='gray', 
            label='Target CDF',
            linestyle = '--')
fig.tight_layout()
return adjusted_figures

channel_figures = return adjusted_figures

file

我们看到每个颜色通道都有显着改善。

此外,请注意上面的函数是如何将所有这些值作为列表返回。这将为我们的最后一步提供很好的帮助,将所有这些重新组合成一张图片。为了让我们更好地了解如何做到这一点,让我们检查一下我们的列表。

print(channel_figures)

file

我们看到在变量channel_figures中有三个列表。这些列表代表RGB通道的值。在下面,我们可以将所有这些值重新组合在一起。

plt.figure(num=None, figsize=(10, 8), dpi=80)

plt.figure(num=None, figsize=(10, 8), dpi=80)
imshow(np.dstack((channel_figures[0][0],
channel_figures[1][0],
channel_figures[2][0])));

file

请注意图像处理前后这种差异是多么显著。图像不仅明亮了许多,黄色的阴影也被移除了。让我们在不同的图像上进行同样的处理试试。

dark_street = imread('dark_street.png');

dark_street = imread('dark_street.png');
plt.figure(num=None, figsize=(8, 6), dpi=80)
imshow(dark_street);

file
现在我们已经加载了新的图片,让我们简单地通过函数来处理。

channel_figures_street = adjusted_image_data = rgb_adjuster_lin(dark_street)

file

plt.figure(num=None, figsize=(10, 8), dpi=80)

file
我们可以看到惊人的变化。不可否认,这张照片曝光有点过度。这可能是因为后面有明显的霓虹灯。在以后的文章中,我们将学习如何微调我们的方法,以使我们的函数更加通用。

总结

在本文中,我们学习了如何调整每个RGB通道以保留图像的颜色信息。这种技术是对以前的灰度调整方法的重大改进。


【AI PC 端算法优化】深入优化 RGB 转灰度图算法

黑人

成为第一个点赞的人吧 :bowtie:
回复数量: 0
暂无回复~
您需要登陆以后才能留下评论!