我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PythonOpenCV直方图均衡化详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

PythonOpenCV直方图均衡化详解

前言

图像处理技术是计算机视觉项目的核心,通常是计算机视觉项目中的关键工具,可以使用它们来完成各种计算机视觉任务。在本文中,将介绍如何使用 OpenCV 函数 cv2.equalizeHist() 执行直方图均衡,并将其应用于灰度和彩色图像,cv2.equalizeHist() 函数将亮度归一化并提高图像的对比度。

灰度直方图均衡化

使用 cv2.equalizeHist() 函数来均衡给定灰度图像的对比度:

# 加载图像并转换为灰度图像
image = cv2.imread('example.png')
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
hist = cv2.calcHist([gray_image], [0], None, [256], [0, 256])
# 直方图均衡化
gray_image_eq = cv2.equalizeHist(gray_image)
# 直方图均衡化后的图像直方图
hist_eq = cv2.calcHist([gray_image_eq], [0], None, [256], [0, 256])

为了深入了解直方图均衡,我们对原始灰度图像进行修改,为图像的每个像素添加/减去 30,并计算直方图均衡前后的直方图:

M = np.ones(gray_image.shape, dtype='uint8') * 30
# 为图像的每个像素添加 30
added_image = cv2.add(gray_image, M)
hist_added_image = cv2.calcHist([added_image], [0], None, [256], [0, 256])
# 直方图均衡化
added_image_eq = cv2.equalizeHist(gray_image_eq)
hist_eq_added_image = cv2.calcHist([added_image_eq], [0], None, [256], [0, 256])
# 为图像的每个像素减去 30
subtracted_image = cv2.subtract(gray_image, M)
hist_subtracted_image = cv2.calcHist([subtracted_image], [0], None, [256], [0, 256])
# 直方图均衡化
subtracted_image_eq = cv2.equalizeHist(subtracted_image)
hist_eq_subtracted_image = cv2.calcHist([subtracted_image_eq], [0], None, [256], [0, 256])

最后,绘制所有这些图像:

def show_img_with_matplotlib(color_img, title, pos):
    img_RGB = color_img[:, :, ::-1]
    ax = plt.subplot(3, 4, pos)
    plt.imshow(img_RGB)
    plt.title(title, fontsize=8)
    plt.axis('off')

def show_hist_with_matplotlib_gray(hist, title, pos, color):
    ax = plt.subplot(3, 4, pos)
    plt.xlabel("bins")
    plt.ylabel("number of pixels")
    plt.xlim([0, 256])
    plt.plot(hist, color=color)
# 可视化
show_img_with_matplotlib(cv2.cvtColor(gray_image, cv2.COLOR_GRAY2BGR), "gray", 1)
show_hist_with_matplotlib_gray(hist, "grayscale histogram", 2, 'm')
show_img_with_matplotlib(cv2.cvtColor(added_image, cv2.COLOR_GRAY2BGR), "gray lighter", 5)
show_hist_with_matplotlib_gray(hist_added_image, "grayscale histogram", 6, 'm')
show_img_with_matplotlib(cv2.cvtColor(subtracted_image, cv2.COLOR_GRAY2BGR), "gray darker", 9)
show_hist_with_matplotlib_gray(hist_subtracted_image, "grayscale histogram", 10, 'm')
# 其他图像的可视化方法类似,不再赘述
# ...

程序运行的输出如下图所示:

在上图中,我们可以看到三个均衡化后的图像非常相似,这也反映在均衡化后的直方图中,这是因为直方图均衡化倾向于标准化图像的亮度,同时增加对比度。

颜色直方图均衡化

使用相同的方法,我们可以在彩色图像中执行直方图均衡,将直方图均衡应用于 BGR 图像的每个通道(虽然这不是彩色图像直方图均衡的最佳方法),创建 equalize_hist_color() 函数,使用 cv2.split() 分割 BGR 图像并将 cv2.equalizeHist() 函数应用于每个通道,最后,使用 cv2.merge() 合并结果通道:

def equalize_hist_color(img):
    # 使用 cv2.split() 分割 BGR 图像
    channels = cv2.split(img)
    eq_channels = []
    # 将 cv2.equalizeHist() 函数应用于每个通道
    for ch in channels:
        eq_channels.append(cv2.equalizeHist(ch))
    # 使用 cv2.merge() 合并所有结果通道
    eq_image = cv2.merge(eq_channels)
    return eq_image

接下来,将此函数应用于三个不同的图像:原始 BGR 图像、将原始图像的每个像素值添加 10、将原始图像的每个像素值减去 10,并计算直方图均衡前后的直方图:

# 加载图像
image = cv2.imread('example.png')
# 计算直方图均衡前后的直方图
hist_color = hist_color_img(image)
image_eq = equalize_hist_color(image)
hist_image_eq = hist_color_img(image_eq)

M = np.ones(image.shape, dtype="uint8") * 10
# 为图像的每个像素添加 10
added_image = cv2.add(image, M)
# 直方图均衡前后的直方图
hist_color_added_image = hist_color_img(added_image)
added_image_eq = equalize_hist_color(added_image)
hist_added_image_eq = hist_color_img(added_image_eq)
# 为图像的每个像素减去 10
subtracted_image = cv2.subtract(image, M)
# 直方图均衡前后的直方图
hist_color_subtracted_image = hist_color_img(subtracted_image)
subtracted_image_eq = equalize_hist_color(subtracted_image)
hist_subtracted_image_eq = hist_color_img(subtracted_image_eq)

最后,绘制所有这些图像:

def show_img_with_matplotlib(color_img, title, pos):
    img_RGB = color_img[:, :, ::-1]
    ax = plt.subplot(3, 4, pos)
    plt.imshow(img_RGB)
    plt.title(title, fontsize=8)
    plt.axis('off')

def show_hist_with_matplotlib_rgb(hist, title, pos, color):
    ax = plt.subplot(3, 4, pos)
    plt.xlabel("bins")
    plt.ylabel("number of pixels")
    plt.xlim([0, 256])
    for (h, c) in zip(hist, color):
        plt.plot(h, color=c)
# 可视化
show_img_with_matplotlib(image, "image", 1)
show_hist_with_matplotlib_rgb(hist_color, "color histogram", 2, ['b', 'g', 'r'])
show_img_with_matplotlib(added_image, "image lighter", 5)
show_hist_with_matplotlib_rgb(hist_color_added_image, "color histogram", 6, ['b', 'g', 'r'])
show_img_with_matplotlib(subtracted_image, "image darker", 9)
show_hist_with_matplotlib_rgb(hist_color_subtracted_image, "color histogram", 10, ['b', 'g', 'r'])
# 其他图像的可视化方法类似,不再赘述
# ...

将直方图均衡化应用于 BGR 图像的每个通道并不是颜色直方图均衡化的好方法,这是由于 BGR 色彩空间的加性特性导致彩色图像的颜色变化很大。由于我们独立地改变三个通道中的亮度和对比度,因此在合并均衡通道时,这可能会导致图像中出现新的色调,正如上图所看到的那样。

一种颜色直方图均衡化更好的方法是将 BGR 图像转换为包含亮度/强度通道的色彩空间( YuvLabHSVHSL )。然后,只在亮度通道上应用直方图均衡,最后合并通道并将它们转换回 BGR 颜色空间,以 HSV 空间为例,创建 equalize_hist_color_hsv() 函数实现上述颜色直方图归一化方法:

def equalize_hist_color_hsv(img):
    H, S, V = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))
    eq_V = cv2.equalizeHist(V)
    eq_image = cv2.cvtColor(cv2.merge([H, S, eq_V]), cv2.COLOR_HSV2BGR)
    return eq_image

接下来,将此函数应用于三个不同的图像:原始 BGR 图像、将原始图像的每个像素值添加 10、将原始图像的每个像素值减去 10,并计算直方图均衡前后的直方图:

hist_color = hist_color_img(image)
# 计算直方图均衡前后的直方图
image_eq = equalize_hist_color_hsv(image)
hist_image_eq = hist_color_img(image_eq)

M = np.ones(image.shape, dtype="uint8") * 10
# 为图像的每个像素添加 10
added_image = cv2.add(image, M)
hist_color_added_image = hist_color_img(added_image)
# 直方图均衡前后的直方图
added_image_eq = equalize_hist_color_hsv(added_image)
hist_added_image_eq = hist_color_img(added_image_eq)
# 为图像的每个像素减去 10
subtracted_image = cv2.subtract(image, M)
hist_color_subtracted_image = hist_color_img(subtracted_image)
# 直方图均衡前后的直方图
subtracted_image_eq = equalize_hist_color_hsv(subtracted_image)
hist_subtracted_image_eq = hist_color_img(subtracted_image_eq)

最后,绘制所有这些图像:

# show_img_with_matplotlib() 和 show_hist_with_matplotlib_rgb() 函数与上一示例相同
show_img_with_matplotlib(image, "image", 1)
show_hist_with_matplotlib_rgb(hist_color, "color histogram", 2, ['b', 'g', 'r'])
show_img_with_matplotlib(added_image, "image lighter", 5)
show_hist_with_matplotlib_rgb(hist_color_added_image, "color histogram", 6, ['b', 'g', 'r'])
# 其他图像的可视化方法类似,不再赘述
# ...

由上图可以看出,仅均衡 HSV 图像的 V 通道得到的结果比均衡 BGR 图像的所有通道的效果要好很多,也可以将这种方法用于其他包含亮度/强度通道的色彩空间( YuvLabHSL )。

以上就是Python OpenCV直方图均衡化详解的详细内容,更多关于OpenCV直方图均衡化的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

PythonOpenCV直方图均衡化详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

matlab直方图均衡化的方法是什么

Matlab中直方图均衡化的方法是通过使用函数histeq来实现。histeq函数可以将图像的直方图进行均衡化,从而增强图像的对比度和亮度。使用方法如下:1. 读取图像:使用imread函数读取要处理的图像。2. 灰度化处理:如果图像是彩色
2023-09-12

matlab彩色直方图均衡化怎么实现

要在MATLAB中实现彩色直方图均衡化,可以按照以下步骤进行操作:1. 读取彩色图像:使用`imread`函数读取原始彩色图像,例如: `img = imread('image.jpg');`2. 将彩色图像转换为HSV色彩空间:使用`rg
2023-09-12

OpenCV-Python直方图均衡化如何实现图像去雾

小编给大家分享一下OpenCV-Python直方图均衡化如何实现图像去雾,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!直方图均衡化直方图均衡化的目的是将原始图像的灰度级均匀地映射到整个灰度级范围内,得到一个灰度级分布均衡的
2023-06-15

Python如何实现直方图、均衡化、高斯滤波

这篇文章将为大家详细讲解有关Python如何实现直方图、均衡化、高斯滤波,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Python直方图、均衡化、高斯滤波测试原图直方图基本原理matplotlib库绘制直
2023-06-08

Pulsar负载均衡原理及优化方案详解

这篇文章主要为大家介绍了Pulsar负载均衡原理及优化方案详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-07

Python生成直方图方法实现详解

这篇文章主要介绍了pythonOpenCV图像直方图处理,文章通过matplotlib画一个直方图展开详情,具有一定的参考价值,需要的小伙伴可以参考一下
2022-11-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录