Opencv 学习笔记:手动绘制彩色图像的 RGB 通道直方图

直方图是分析图像像素分布的核心工具,本文通过自定义函数实现彩色图像 BGR 三通道直方图的手动绘制,新手可直观理解直方图的计算与可视化逻辑。

核心代码实现

python 复制代码
import cv2 as cv
import numpy as np

# 定义计算并绘制直方图的函数
def calcanddrawhist(src, color):
    # 1. 计算直方图:[图像], [通道索引], 掩膜, 直方图条数, 像素值范围
    hist = cv.calcHist([src], [0], None, [256], [0.0, 255.0])
    
    # 2. 获取直方图最大值(用于归一化)
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(hist)
    
    # 3. 创建256×256的空白画布(用于绘制直方图)
    hist_img = np.zeros([256, 256, 3], np.uint8)
    hpt = int(0.9 * 256)  # 限制直方图高度(预留10%边距)
    
    # 4. 遍历每个像素值,绘制直方图线条
    for h in range(256):
        # 归一化直方图数值到画布高度范围
        intensity = int(hist[h] * hpt / max_val)
        # 绘制垂直线:从底部向上,颜色为指定通道色
        cv.line(hist_img, (h, 256), (h, 256-intensity), color)
    
    return hist_img

# 主程序
src = cv.imread('.\image\1.bmp')
if src is None:
    print('could not load image')
    exit()
cv.imshow('src', src)

# 拆分BGR通道
b, g, r = cv.split(src)

# 分别计算并绘制各通道直方图
hist_imgb = calcanddrawhist(b, [255, 0, 0])  # 蓝色通道(B)
hist_imgg = calcanddrawhist(g, [0, 255, 0])  # 绿色通道(G)
hist_imgr = calcanddrawhist(r, [0, 0, 255])  # 红色通道(R)

# 显示各通道直方图
cv.imshow('his_b', hist_imgb)
cv.imshow('his_g', hist_imgg)
cv.imshow('his_r', hist_imgr)

cv.waitKeyEx(0)
cv.destroyAllWindows()

关键知识点解析

1. 直方图绘制核心流程

步骤 核心 API / 操作 作用说明
计算直方图 cv.calcHist() 统计每个像素值(0-255)的出现次数
归一化 hist[h] * hpt/max_val 将直方图数值缩放到画布高度范围,避免超出画布
绘制线条 cv.line() 以像素值为 x 轴,出现次数为 y 轴,绘制垂直线条

2. 关键参数说明

  • cv.calcHist([src], [0], None, [256], [0.0, 255.0]):
    • [src]:输入图像(需为列表格式);
    • [0]:通道索引(单通道处理时固定为 0);
    • None:无掩膜(分析整幅图像);
    • [256]:直方图条数(对应 0-255 像素值);
    • [0.0, 255.0]:像素值范围。
  • hpt = int(0.9 * 256):预留 10% 画布边距,避免直方图顶边溢出。

3. 优化与扩展技巧

  • 合并显示 :将三个通道直方图拼接为一张图,更便于对比:

    python

    运行

    python 复制代码
    hist_merge = cv.hconcat([hist_imgb, hist_imgg, hist_imgr])
    cv.imshow('hist_merge', hist_merge)
  • 灰度图直方图 :无需拆分通道,直接传入灰度图即可:

    python

    运行

    python 复制代码
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
    hist_gray = calcanddrawhist(gray, [255, 255, 255])  # 白色线条
  • 效率优化:循环绘制可改用 numpy 向量化操作,提升大图像处理速度。

总结

  1. 直方图绘制核心是cv.calcHist()统计像素分布,再通过归一化 + 画线实现可视化;
  2. 彩色图像需拆分 BGR 通道分别绘制,通道颜色与线条颜色对应更易区分;
  3. 归一化步骤是关键,可避免直方图数值超出画布范围导致显示异常。
相关推荐
来包番茄沙司6 分钟前
【网盘资源分享】2026新版尚硅谷AI Agent智能体极速版|全套课程资料+面经
人工智能·学习
每天题库22 分钟前
塔式起重机安装拆卸工考试题库 真题模拟考前押题精准覆盖
学习·安全·考试·题库·考证
别动我齐刘海10 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
志尊宝11 小时前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
沪上企服通12 小时前
历史账套科目重映射与规则版本重算:旧账梳理的“口径复位”工程
笔记·架构
gjf05_0513 小时前
人该怎样活着呢?版本75.8
学习
li星野14 小时前
【学习记录】PCB与PCBA核心知识全解析:从设计到制造的关键细节
学习·制造
卿卿的产品经理日记15 小时前
【AI产品经理实战】Day 35|从“沉迷工具“到回归 AI 底层:Skill 收官、系统复盘与下一个 13 天
人工智能·学习·产品经理
一条泥憨鱼16 小时前
【从0开始学习计算机网络】| ARP 协议:地址解析,ARP 欺骗,链路层寻址
网络·后端·学习·计算机网络
HY小宝F16 小时前
树莓派智能摄像头系统 30 天重学计划之 Day 04 · HTTP / API:控制链入口 —— 学习总结
网络协议·学习·http