飞道的博客

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

432人阅读  评论(0)

欢迎关注 “小白玩转Python”,发现更多 “有趣”

引言

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

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


   
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from skimage.io import imread, imshow
  4. import matplotlib.pyplot as plt
  5. from skimage.exposure import histogram, cumulative_distribution
  6. from scipy.stats import norm

现在让我们载入图像。


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

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


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

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


   
  1. def df_plotter(image):
  2. freq_bins = [cumulative_distribution(image[:,:,i]) for i in
  3. range( 3)]
  4. target_bins = np.arange( 255)
  5. target_freq = np.linspace( 0, 1, len(target_bins))
  6. names = [ 'Red', 'Green', 'Blue']
  7. line_color = [ 'red', 'green', 'blue']
  8. f_size = 20
  9. fig, ax = plt.subplots( 1, 3, figsize=( 17, 5))
  10. for n, ax in enumerate(ax.flatten()):
  11. ax.set_title( f'{names[n]}', fontsize = f_size)
  12. ax.step(freq_bins[n][ 1], freq_bins[n][ 0], c=line_color[n],
  13. label= 'Actual CDF')
  14. ax.plot(target_bins,
  15. target_freq,
  16. c= 'gray',
  17. label= 'Target CDF',
  18. linestyle = '--')
  19. df_plotter(dark_image)

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


   
  1. def rgb_adjuster_lin(image):
  2. target_bins = np.arange( 255)
  3. target_freq = np.linspace( 0, 1, len(target_bins))
  4. freq_bins = [cumulative_distribution(image[ :, :,i]) for i in
  5. range( 3)]
  6. names = [ 'Reds', 'Blues', 'Greens']
  7. line_color = [ 'red', 'green', 'blue']
  8. adjusted_figures = []
  9. f_size = 20
  10. fig, ax = plt.subplots( 1, 3, figsize=[ 15, 5])
  11. for n, ax in enumerate(ax.flatten()):
  12. interpolation = np.interp(freq_bins[n][ 0], target_freq,
  13. target_bins)
  14. adjusted_image = img_as_ubyte(interpolation[image[ :, :,
  15. n]].astype(int))
  16. ax.set_title(f '{names[n]}', fontsize = f_size)
  17. ax.imshow(adjusted_image, cmap = names[n])
  18. adjusted_figures.append([adjusted_image])
  19. fig.tight_layout()
  20. fig, ax = plt.subplots( 1, 3, figsize=[ 15, 5])
  21. for n, ax in enumerate(ax.flatten()):
  22. interpolation = np.interp(freq_bins[n][ 0], target_freq,
  23. target_bins)
  24. adjusted_image = img_as_ubyte(interpolation[image[ :, :,
  25. n]].astype(int))
  26. freq_adj, bins_adj = cumulative_distribution(adjusted_image)
  27. ax.set_title(f '{names[n]}', fontsize = f_size)
  28. ax.step(bins_adj, freq_adj, c=line_color[n], label= 'Actual
  29. CDF')
  30. ax.plot(target_bins,
  31. target_freq,
  32. c= 'gray',
  33. label= 'Target CDF',
  34. linestyle = '--')
  35. fig.tight_layout()
  36. return adjusted_figures
  37. channel_figures = return adjusted_figures

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

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


   
  1. print(channel_figures)
  2. print( f'Total Inner Lists : {len(channel_figures)}')

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


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

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


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

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

channel_figures_street = adjusted_image_data = rgb_adjuster_lin(dark_street)


   
  1. plt.figure(num=None, figsize=(10, 8), dpi=80)
  2. imshow(np.dstack((channel _figures_street [ 0][ 0],
  3. channel_figures_street [1][0],
  4.                   channel_figures_street [2][0])));

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

总结

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

·  END  ·

HAPPY LIFE


转载:https://blog.csdn.net/weixin_38739735/article/details/111829448
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场