返回顶部
首页 > 资讯 > 后端开发 > Python >Python+OpenCV怎么解决彩色图亮度不均衡问题
  • 180
分享到

Python+OpenCV怎么解决彩色图亮度不均衡问题

2023-06-22 06:06:44 180人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍“python+OpenCV怎么解决彩色图亮度不均衡问题”,在日常操作中,相信很多人在Python+OpenCV怎么解决彩色图亮度不均衡问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Pyt

这篇文章主要介绍“python+OpenCV怎么解决彩色图亮度不均衡问题”,在日常操作中,相信很多人在Python+OpenCV怎么解决彩色图亮度不均衡问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python+OpenCV怎么解决彩色图亮度不均衡问题”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

处理

对比度拉伸

也就是把图像重新缩放到指定的范围内

# 对比度拉伸p1, p2 = np.percentile(img, (0, 70))  # numpy计算多维数组的任意百分比分位数rescale_img = np.uint8((np.clip(img, p1, p2) - p1) / (p2 - p1) * 255)

其中,numpy的percentile函数可以计算多维数组的任意百分比分位数,因为我的图片中整体偏暗,我就把原图灰度值的0% ~ 70%缩放到0 ~255

log变换

使用以下公式进行映射:

Python+OpenCV怎么解决彩色图亮度不均衡问题

# 对数变换log_img = np.zeros_like(img)scale, gain = 255, 1.5for i in range(3):    log_img[:, :, i] = np.log(img[:, :, i] / scale + 1) * scale * gain

Gamma校正

使用以下公式进行映射:

Python+OpenCV怎么解决彩色图亮度不均衡问题

# gamma变换gamma, gain, scale = 0.7, 1, 255gamma_img = np.zeros_like(img)for i in range(3):    gamma_img[:, :, i] = ((img[:, :, i] / scale) ** gamma) * scale * gain

直方图均衡化

使用直方图均衡后的图像具有大致线性的累积分布函数,其优点是不需要参数。

其原理为,考虑这样一个图像,它的像素值被限制在某个特定的值范围内,即灰度范围不均匀。所以我们需要将其直方图缩放遍布整个灰度范围(如下图所示,来自维基百科),这就是直方图均衡化所做的(简单来说)。这通常会提高图像的对比度。

Python+OpenCV怎么解决彩色图亮度不均衡问题

这里使用OpenCV来演示。

# 直方图均衡化equa_img = np.zeros_like(img)for i in range(3):    equa_img[:, :, i] = cv.equalizeHist(img[:, :, i])

对比度自适应直方图均衡化(CLAHE)

这是一种自适应直方图均衡化方法

OpenCV提供了该方法。

# 对比度自适应直方图均衡化clahe_img = np.zeros_like(img)clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))for i in range(3):    clahe_img[:, :, i] = clahe.apply(img[:, :, i])

处理结果展示

使用Matplotlib显示上述几种方法的结果:

Python+OpenCV怎么解决彩色图亮度不均衡问题

可以看到,前四种方法效果都差不多,都有一个问题亮的地方过于亮,这是因为他们考虑的是全局对比度,而且因为我们使用的彩色图像原因,使用log变换的结果图中有部分区域色彩失真。最后一种CLAHE方法考虑的是局部对比度,所以效果会好一点。

因为图像是彩色的,这里我只绘制了R通道的直方图(红色线)及其累积分布函数(黑色线)

Python+OpenCV怎么解决彩色图亮度不均衡问题

可以看到均衡后的图像具有大致线性的累积分布函数。

总之,经过以上的探索,我最终决定使用CLAHE均衡后的结果,感觉是比之前的好了点

源码

opencv版本

import cv2.cv2 as cvimport matplotlib.pyplot as pltimport numpy as npdef plot_img_and_hist(image, axes, bins=256):    """Plot an image along with its histogram and cumulative histogram.    """    ax_img, ax_hist = axes    ax_cdf = ax_hist.twinx()    # Display image    ax_img.imshow(image, cmap=plt.cm.gray)    ax_img.set_axis_off()    # Display histogram    colors = ['red', 'green', 'blue']    for i in range(1):        ax_hist.hist(image[:, :, i].ravel(), bins=bins, histtype='step', color=colors[i])    ax_hist.ticklabel_fORMat(axis='y', style='scientific', scilimits=(0, 0))    ax_hist.set_xlabel('Pixel intensity')    ax_hist.set_xlim(0, 255)    # 这里范围为0~255 如果使用img_as_float,则这里为0~1    ax_hist.set_yticks([])    # Display cumulative distribution    for i in range(1):        hist, bins = np.histogram(image[:, :, i].flatten(), 256, [0, 256])        cdf = hist.cumsum()        cdf = cdf * float(hist.max()) / cdf.max()        ax_cdf.plot(bins[1:], cdf, 'k')    ax_cdf.set_yticks([])    return ax_img, ax_hist, ax_cdfdef plot_all(images, titles, cols):    """    输入titles、images、以及每一行多少列,自动计算行数、并绘制图像和其直方图    :param images:    :param titles:    :param cols: 每一行多少列    :return:    """    fig = plt.figure(figsize=(12, 8))    img_num = len(images)  # 图片的个数    rows = int(np.ceil(img_num / cols) * 2)  # 上图下直方图 所以一共显示img_num*2个子图    axes = np.zeros((rows, cols), dtype=object)    axes = axes.ravel()    axes[0] = fig.add_subplot(rows, cols, 1)  # 先定义第一个img 单独拿出来定义它是为了下面的sharex    # 开始创建所有的子窗口    for i in range(1, img_num):  #        axes[i + i // cols * cols] = fig.add_subplot(rows, cols, i + i // cols * cols + 1, sharex=axes[0],                                                     sharey=axes[0])    for i in range(0, img_num):        axes[i + i // cols * cols + cols] = fig.add_subplot(rows, cols, i + i // cols * cols + cols + 1)    for i in range(0, img_num):  # 这里从1开始,因为第一个在上面已经绘制过了        ax_img, ax_hist, ax_cdf = plot_img_and_hist(images[i],                                                    (axes[i + i // cols * cols], axes[i + i // cols * cols + cols]))        ax_img.set_title(titles[i])        y_min, y_max = ax_hist.get_ylim()        ax_hist.set_ylabel('Number of pixels')        ax_hist.set_yticks(np.linspace(0, y_max, 5))        ax_cdf.set_ylabel('Fraction of total intensity')        ax_cdf.set_yticks(np.linspace(0, 1, 5))    # prevent overlap of y-axis labels    fig.tight_layout()    plt.show()    plt.close(fig)if __name__ == '__main__':    img = cv.imread('catandmouse.png', cv.IMREAD_UNCHANGED)[:, :, :3]    img = cv.cvtColor(img, cv.COLOR_BGR2RGB)    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)    # 对比度拉伸    p1, p2 = np.percentile(img, (0, 70))  # numpy计算多维数组的任意百分比分位数    rescale_img = np.uint8((np.clip(img, p1, p2) - p1) / (p2 - p1) * 255)    # 对数变换    log_img = np.zeros_like(img)    scale, gain = 255, 1.5    for i in range(3):        log_img[:, :, i] = np.log(img[:, :, i] / scale + 1) * scale * gain    # gamma变换    gamma, gain, scale = 0.7, 1, 255    gamma_img = np.zeros_like(img)    for i in range(3):        gamma_img[:, :, i] = ((img[:, :, i] / scale) ** gamma) * scale * gain    # 彩色图直方图均衡化    # 直方图均衡化    equa_img = np.zeros_like(img)    for i in range(3):        equa_img[:, :, i] = cv.equalizeHist(img[:, :, i])    # 对比度自适应直方图均衡化    clahe_img = np.zeros_like(img)    clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))    for i in range(3):        clahe_img[:, :, i] = clahe.apply(img[:, :, i])    titles = ['img', 'rescale', 'log', 'gamma', 'equalizeHist', 'CLAHE']    images = [img, rescale_img, log_img, gamma_img, equa_img, clahe_img]    plot_all(images, titles, 3)

skimage版本

from skimage import exposure, util, io, color, filters, morphologyimport matplotlib.pyplot as pltimport numpy as npdef plot_img_and_hist(image, axes, bins=256):    """Plot an image along with its histogram and cumulative histogram.    """    image = util.img_as_float(image)    ax_img, ax_hist = axes    ax_cdf = ax_hist.twinx()    # Display image    ax_img.imshow(image, cmap=plt.cm.gray)    ax_img.set_axis_off()    # Display histogram    colors = ['red', 'green', 'blue']    for i in range(1):        ax_hist.hist(image[:, :, i].ravel(), bins=bins, histtype='step', color=colors[i])    ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0))    ax_hist.set_xlabel('Pixel intensity')    ax_hist.set_xlim(0, 1)    ax_hist.set_yticks([])    # Display cumulative distribution    for i in range(1):        img_cdf, bins = exposure.cumulative_distribution(image[:, :, i], bins)        ax_cdf.plot(bins, img_cdf, 'k')    ax_cdf.set_yticks([])    return ax_img, ax_hist, ax_cdfdef plot_all(images, titles, cols):    """    输入titles、images、以及每一行多少列,自动计算行数、并绘制图像和其直方图    :param images:    :param titles:    :param cols: 每一行多少列    :return:    """    fig = plt.figure(figsize=(12, 8))    img_num = len(images)  # 图片的个数    rows = int(np.ceil(img_num / cols) * 2)  # 上图下直方图 所以一共显示img_num*2个子图    axes = np.zeros((rows, cols), dtype=object)    axes = axes.ravel()    axes[0] = fig.add_subplot(rows, cols, 1)  # 先定义第一个img 单独拿出来定义它是为了下面的sharex    # 开始创建所有的子窗口    for i in range(1, img_num):  #        axes[i + i // cols * cols] = fig.add_subplot(rows, cols, i + i // cols * cols + 1, sharex=axes[0],                                                     sharey=axes[0])    for i in range(0, img_num):        axes[i + i // cols * cols + cols] = fig.add_subplot(rows, cols, i + i // cols * cols + cols + 1)    for i in range(0, img_num):  # 这里从1开始,因为第一个在上面已经绘制过了        ax_img, ax_hist, ax_cdf = plot_img_and_hist(images[i],                                                    (axes[i + i // cols * cols], axes[i + i // cols * cols + cols]))        ax_img.set_title(titles[i])        y_min, y_max = ax_hist.get_ylim()        ax_hist.set_ylabel('Number of pixels')        ax_hist.set_yticks(np.linspace(0, y_max, 5))        ax_cdf.set_ylabel('Fraction of total intensity')        ax_cdf.set_yticks(np.linspace(0, 1, 5))    # prevent overlap of y-axis labels    fig.tight_layout()    plt.show()    plt.close(fig)if __name__ == '__main__':    img = io.imread('catandmouse.png')[:, :, :3]    gray = color.rgb2gray(img)    # 对比度拉伸    p1, p2 = np.percentile(img, (0, 70))  # numpy计算多维数组的任意百分比分位数    rescale_img = exposure.rescale_intensity(img, in_range=(p1, p2))    # 对数变换    # img = util.img_as_float(img)    log_img = np.zeros_like(img)    for i in range(3):        log_img[:, :, i] = exposure.adjust_log(img[:, :, i], 1.2, False)    # gamma变换    gamma_img = np.zeros_like(img)    for i in range(3):        gamma_img[:, :, i] = exposure.adjust_gamma(img[:, :, i], 0.7, 2)    # 彩色图直方图均衡化    equa_img = np.zeros_like(img, dtype=np.float64)  # 注意直方图均衡化输出值为float类型的    for i in range(3):        equa_img[:, :, i] = exposure.equalize_hist(img[:, :, i])    # 对比度自适应直方图均衡化    clahe_img = np.zeros_like(img, dtype=np.float64)    for i in range(3):        clahe_img[:, :, i] = exposure.equalize_adapthist(img[:, :, i])    # 局部直方图均衡化 效果不好就不放了    selem = morphology.rectangle(50, 50)    loc_img = np.zeros_like(img)    for i in range(3):        loc_img[:, :, i] = filters.rank.equalize(util.img_as_ubyte(img[:, :, i]), footprint=selem)    # Display results    titles = ['img', 'rescale', 'log', 'gamma', 'equalizeHist', 'CLAHE']    images = [img, rescale_img, log_img, gamma_img, equa_img, clahe_img]    plot_all(images, titles, 3)

到此,关于“Python+OpenCV怎么解决彩色图亮度不均衡问题”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Python+OpenCV怎么解决彩色图亮度不均衡问题

本文链接: https://lsjlt.com/news/303272.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python+OpenCV解决彩色图亮度不均衡问题
    目录前言处理对比度拉伸log变换Gamma校正直方图均衡化对比度自适应直方图均衡化(CLAHE)处理结果展示附源码opencv版本skimage版本前言 CSDN博客好久没有换过头像...
    99+
    2024-04-02
  • Python+OpenCV怎么解决彩色图亮度不均衡问题
    这篇文章主要介绍“Python+OpenCV怎么解决彩色图亮度不均衡问题”,在日常操作中,相信很多人在Python+OpenCV怎么解决彩色图亮度不均衡问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Pyt...
    99+
    2023-06-22
  • 负载均衡带宽问题怎么解决
    解决负载均衡带宽问题可以从以下几个方面入手:1. 增加带宽:可以联系网络服务提供商,升级带宽套餐或者增加带宽容量,以提高网络传输速度...
    99+
    2023-09-01
    负载均衡
  • 怎么解决vuejs devtools不亮了的问题
    本篇内容介绍了“怎么解决vuejs devtools不亮了的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!vuejs devtools不...
    99+
    2023-06-25
  • 怎么解决php长度不足问题
    这篇文章主要介绍“怎么解决php长度不足问题”,在日常操作中,相信很多人在怎么解决php长度不足问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么解决php长度不足问题”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-25
  • python3 opencv图像二值化的问题怎么解决
    这篇“python3 opencv图像二值化的问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“pytho...
    99+
    2023-06-29
  • Python中怎么解决非平衡数据问题
    Python中怎么解决非平衡数据问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。SMOTE算法的介绍在实际应用中,读者可能会碰到一种比较头疼的问题,那就是分类...
    99+
    2023-06-17
  • css怎么解决高度不一致问题
    这篇文章主要为大家展示了“css怎么解决高度不一致问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“css怎么解决高度不一致问题”这篇文章吧。 ...
    99+
    2024-04-02
  • HTML怎么解决高度不适应问题
    这篇文章主要介绍了HTML怎么解决高度不适应问题的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇HTML怎么解决高度不适应问题文章都会有所收获,下面我们一起来看看吧。 高度不适...
    99+
    2024-04-02
  • pip安装opencv-python遇到的问题怎么解决
    今天小编给大家分享一下pip安装opencv-python遇到的问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。p...
    99+
    2023-07-05
  • 使用python怎么解决OpenCV在读取显示图片闪退的问题
    使用python怎么解决OpenCV在读取显示图片闪退的问题?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。waitKey函数:用来等待按键,当用户按下按键后,该...
    99+
    2023-06-06
  • 怎么解决win7桌面图标打不开问题
    这篇文章给大家分享的是有关怎么解决win7桌面图标打不开问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先双击打开桌面上的“计算机”图标,在计算机界面中单击菜单栏的“工具--文件夹选项”。在弹出来的文件夹选项...
    99+
    2023-06-28
  • Java调度线程池ScheduledThreadPoolExecutor不执行问题怎么解决
    本篇内容主要讲解“Java调度线程池ScheduledThreadPoolExecutor不执行问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java调度线程池ScheduledTh...
    99+
    2023-07-05
  • python列表切片超出长度问题怎么解决
    当切片的结束位置超出列表的长度时,Python会自动将结束位置设置为列表的最后一个元素的索引加1。因此,可以通过判断切片的结束位置是...
    99+
    2024-02-29
    python
  • jquery轮播图不显示锚点问题怎么解决
    这篇文章主要介绍“jquery轮播图不显示锚点问题怎么解决”,在日常操作中,相信很多人在jquery轮播图不显示锚点问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jquery轮播图不显示锚点问题怎...
    99+
    2023-07-06
  • Python怎么解决图表与画布的间距问题
    本篇内容主要讲解“Python怎么解决图表与画布的间距问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python怎么解决图表与画布的间距问题”吧!1.问题情境我们使用python的 matp...
    99+
    2023-06-30
  • php怎么解决同样的字符串长度不一样问题
    这篇文章主要介绍“php怎么解决同样的字符串长度不一样问题”,在日常操作中,相信很多人在php怎么解决同样的字符串长度不一样问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php怎么解决同样的字符串长度不一...
    99+
    2023-07-05
  • python元组的可变与不可变问题怎么解决
    本文小编为大家详细介绍“python元组的可变与不可变问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“python元组的可变与不可变问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。pytho...
    99+
    2023-07-04
  • php开发中怎么解决微信图片发送不了问题
    在使用微信公众号进行开发和维护时,我们经常会遇到图片无法正常发送的问题。特别是在使用PHP语言进行开发时,因为微信公众号的API接口文档不够详细的原因,图片无法正常发送的问题显得更加棘手。本文将详细介绍微信PHP如何处理发送图片的问题,并提...
    99+
    2023-05-14
  • 怎么解决windows10桌面底部任务栏不显示图标问题
    这篇文章给大家分享的是有关怎么解决windows10桌面底部任务栏不显示图标问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。windows10桌面底部任务栏不显示图标可能是被隐藏了。首先在底部任务栏右键,选择最...
    99+
    2023-06-27
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作