Python matplotlib怎么绘制灰度和彩色直方图

发布时间:2021-12-24 09:05:34 作者:柒染
来源:亿速云 阅读:335
# Python matplotlib怎么绘制灰度和彩色直方图

直方图是图像处理中分析像素分布的重要工具。本文将详细介绍如何使用Python的matplotlib库绘制灰度图像和彩色图像的直方图,包含完整代码示例和可视化效果分析。

## 一、直方图基础概念

### 1.1 什么是直方图
直方图(Histogram)是图像像素强度分布的图形表示,横轴代表像素值(0-255),纵轴代表该像素值在图像中出现的频率。

### 1.2 直方图的作用
- 分析图像对比度
- 检测曝光问题
- 图像分割阈值选择
- 颜色校正依据

## 二、准备工作

### 2.1 安装必要库
```python
pip install matplotlib numpy opencv-python

2.2 导入库

import cv2
import numpy as np
import matplotlib.pyplot as plt

三、灰度图像直方图绘制

3.1 读取灰度图像

gray_img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

3.2 基础绘制方法

plt.hist(gray_img.ravel(), bins=256, range=[0, 256])
plt.title('Grayscale Histogram')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.show()

3.3 带样式优化的直方图

plt.figure(figsize=(10, 6))
plt.hist(gray_img.ravel(), bins=256, range=[0, 256], 
         color='gray', alpha=0.7, edgecolor='black')
plt.title('Enhanced Grayscale Histogram', fontsize=14)
plt.xlabel('Pixel Intensity', fontsize=12)
plt.ylabel('Pixel Count', fontsize=12)
plt.grid(axis='y', alpha=0.5)
plt.xlim([0, 256])
plt.show()

3.4 多子图对比示例

images = [gray_img, cv2.equalizeHist(gray_img)]
titles = ['Original', 'Histogram Equalized']

plt.figure(figsize=(12, 6))
for i, (img, title) in enumerate(zip(images, titles)):
    plt.subplot(1, 2, i+1)
    plt.hist(img.ravel(), bins=256, range=[0, 256])
    plt.title(title)
plt.tight_layout()
plt.show()

四、彩色图像直方图绘制

4.1 读取彩色图像

color_img = cv2.imread('color_image.jpg')
color_img = cv2.cvtColor(color_img, cv2.COLOR_BGR2RGB)  # 转换通道顺序

4.2 单通道分别绘制

colors = ('r', 'g', 'b')
plt.figure(figsize=(10, 6))
for i, color in enumerate(colors):
    hist = cv2.calcHist([color_img], [i], None, [256], [0, 256])
    plt.plot(hist, color=color)
plt.title('Color Channel Histograms')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.legend(['Red', 'Green', 'Blue'])
plt.show()

4.3 堆叠式直方图

plt.figure(figsize=(10, 6))
for i, color in enumerate(colors):
    hist = cv2.calcHist([color_img], [i], None, [256], [0, 256])
    plt.plot(hist, color=color, linewidth=2)
    plt.fill_between(range(256), hist.ravel(), color=color, alpha=0.3)
plt.title('Stacked Color Histogram', fontsize=14)
plt.xlabel('Pixel Intensity', fontsize=12)
plt.ylabel('Pixel Count', fontsize=12)
plt.grid(alpha=0.2)
plt.show()

4.4 三维直方图表示

from mpl_toolkits.mplot3d import Axes3D

# 创建3D坐标轴
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# 为每个通道生成数据
bins = np.arange(256)
for c, z, color in zip([0, 1, 2], [0, 50, 100], ['r', 'g', 'b']):
    hist = cv2.calcHist([color_img], [c], None, [256], [0, 256])
    ax.bar(bins, hist.ravel(), zs=z, zdir='y', color=color, alpha=0.7)

ax.set_xlabel('Pixel Value')
ax.set_ylabel('Color Channel')
ax.set_zlabel('Frequency')
ax.set_yticks([0, 50, 100])
ax.set_yticklabels(['Red', 'Green', 'Blue'])
plt.title('3D Color Histogram')
plt.show()

五、高级应用技巧

5.1 直方图均衡化对比

# 分离通道
channels = cv2.split(color_img)
eq_channels = []
for ch in channels:
    eq_channels.append(cv2.equalizeHist(ch))
    
eq_img = cv2.merge(eq_channels)

# 绘制对比
plt.figure(figsize=(14, 8))
for i, (img, title) in enumerate(zip([color_img, eq_img], 
                                   ['Original', 'Equalized'])):
    plt.subplot(2, 1, i+1)
    for j, color in enumerate(colors):
        hist = cv2.calcHist([img], [j], None, [256], [0, 256])
        plt.plot(hist, color=color)
    plt.title(f'{title} Image Histogram')
    plt.legend(['Red', 'Green', 'Blue'])
plt.tight_layout()
plt.show()

5.2 直方图匹配

def hist_match(source, template):
    # 计算源图像和目标图像的累积直方图
    src_hist = cv2.calcHist([source], [0], None, [256], [0,256]).cumsum()
    tmpl_hist = cv2.calcHist([template], [0], None, [256], [0,256]).cumsum()
    
    # 归一化
    src_hist = (src_hist - src_hist.min()) / (src_hist.max() - src_hist.min()) * 255
    tmpl_hist = (tmpl_hist - tmpl_hist.min()) / (tmpl_hist.max() - tmpl_hist.min()) * 255
    
    # 创建LUT
    lut = np.interp(src_hist, tmpl_hist, np.arange(256))
    return cv2.LUT(source, lut.astype('uint8'))

# 应用示例
matched = hist_match(gray_img, template_img)

六、性能优化技巧

  1. 降采样处理:对大图像可先缩小尺寸

    small_img = cv2.resize(img, (0,0), fx=0.25, fy=0.25)
    
  2. 使用numpy函数:比OpenCV更快

    hist, bins = np.histogram(img.ravel(), 256, [0,256])
    
  3. 限制bin数量:减少计算量

    plt.hist(img.ravel(), bins=64, range=[0, 256])
    

七、常见问题解答

Q1:直方图右侧有大量空白? A:说明图像像素集中在低值区域,可尝试调整显示范围:

plt.xlim([0, np.max(img)*1.1])

Q2:如何比较两个直方图?

# 使用直方图比较方法
correl = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)

Q3:直方图峰值不明显? 可尝试对数变换:

plt.yscale('log')

八、总结

本文详细介绍了使用matplotlib绘制图像直方图的各种方法,包括: - 基础灰度直方图绘制 - 多通道彩色直方图可视化 - 3D直方图等高级技巧 - 直方图均衡化和匹配应用

掌握这些技术能够帮助您更好地分析图像特征,为后续的图像处理任务打下基础。 “`

推荐阅读:
  1. python中matplotlib库直方图怎么绘制
  2. python中plotly如何绘制直方图

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python matplotlib

上一篇:Android跟随手指移动的控件demo怎么实现

下一篇:linux中如何删除用户组

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》