亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python+OpenCV解決彩色圖亮度不均衡問(wèn)題

 更新時(shí)間:2021年12月31日 14:55:34   作者:薛定貓  
當(dāng)我們換新頭像時(shí),常常會(huì)遇到圖片過(guò)暗導(dǎo)致看不到圖片內(nèi)容的情況,本文將介紹如何通過(guò)Python和OpenCV解決色彩圖亮度不均衡的問(wèn)題,需要的可以參考一下

前言

CSDN博客好久沒有換過(guò)頭像了,想換個(gè)新頭像,在相冊(cè)里面翻來(lái)翻去,然后就找到以前養(yǎng)的小寵物的一些照片,有一張?zhí)貏e有意思

驚恐到站起來(lái)的金絲熊:這家伙不會(huì)要吃我吧

沒見過(guò)倉(cāng)鼠的小貓:這啥玩意兒?

好,就決定把這張圖當(dāng)自己的頭像了

一頓操作之后,把頭像換成了這張照片

此時(shí)我:啥玩意兒?

。。。。感覺黑乎乎的,啥也看不清

這時(shí)候我想起來(lái)我學(xué)過(guò)圖像處理,這用亮度變換搞一下不就可以了嗎,搞起來(lái)!

注意:一般對(duì)灰度圖進(jìn)行亮度變換的多一點(diǎn),但是我這張圖是RGB圖(準(zhǔn)確來(lái)說(shuō)是RGBA,但我們只取前三個(gè)通道),對(duì)于RGB圖,我這里對(duì)其每個(gè)通道分別進(jìn)行處理然后拼接處理

處理

對(duì)比度拉伸

也就是把圖像重新縮放到指定的范圍內(nèi)

# 對(duì)比度拉伸
p1, p2 = np.percentile(img, (0, 70))  # numpy計(jì)算多維數(shù)組的任意百分比分位數(shù)
rescale_img = np.uint8((np.clip(img, p1, p2) - p1) / (p2 - p1) * 255)

其中,numpy的percentile函數(shù)可以計(jì)算多維數(shù)組的任意百分比分位數(shù),因?yàn)槲业膱D片中整體偏暗,我就把原圖灰度值的0% ~ 70%縮放到0 ~255

log變換

使用以下公式進(jìn)行映射:

# 對(duì)數(shù)變換
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校正

使用以下公式進(jìn)行映射:

# 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

直方圖均衡化

使用直方圖均衡后的圖像具有大致線性的累積分布函數(shù),其優(yōu)點(diǎn)是不需要參數(shù)。

其原理為,考慮這樣一個(gè)圖像,它的像素值被限制在某個(gè)特定的值范圍內(nèi),即灰度范圍不均勻。所以我們需要將其直方圖縮放遍布整個(gè)灰度范圍(如下圖所示,來(lái)自維基百科),這就是直方圖均衡化所做的(簡(jiǎn)單來(lái)說(shuō))。這通常會(huì)提高圖像的對(duì)比度。

這里使用OpenCV來(lái)演示。

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

對(duì)比度自適應(yīng)直方圖均衡化(CLAHE)

這是一種自適應(yīng)直方圖均衡化方法

OpenCV提供了該方法。

# 對(duì)比度自適應(yīng)直方圖均衡化
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])

處理結(jié)果展示

使用Matplotlib顯示上述幾種方法的結(jié)果:

可以看到,前四種方法效果都差不多,都有一個(gè)問(wèn)題亮的地方過(guò)于亮,這是因?yàn)樗麄兛紤]的是全局對(duì)比度,而且因?yàn)槲覀兪褂玫牟噬珗D像原因,使用log變換的結(jié)果圖中有部分區(qū)域色彩失真。最后一種CLAHE方法考慮的是局部對(duì)比度,所以效果會(huì)好一點(diǎn)。

因?yàn)閳D像是彩色的,這里我只繪制了R通道的直方圖(紅色線)及其累積分布函數(shù)(黑色線)

可以看到均衡后的圖像具有大致線性的累積分布函數(shù)。

總之,經(jīng)過(guò)以上的探索,我最終決定使用CLAHE均衡后的結(jié)果

感覺是比之前的好了點(diǎn)

附源碼

opencv版本

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


def 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_cdf


def plot_all(images, titles, cols):
    """
    輸入titles、images、以及每一行多少列,自動(dòng)計(jì)算行數(shù)、并繪制圖像和其直方圖
    :param images:
    :param titles:
    :param cols: 每一行多少列
    :return:
    """
    fig = plt.figure(figsize=(12, 8))
    img_num = len(images)  # 圖片的個(gè)數(shù)
    rows = int(np.ceil(img_num / cols) * 2)  # 上圖下直方圖 所以一共顯示img_num*2個(gè)子圖
    axes = np.zeros((rows, cols), dtype=object)
    axes = axes.ravel()
    axes[0] = fig.add_subplot(rows, cols, 1)  # 先定義第一個(gè)img 單獨(dú)拿出來(lái)定義它是為了下面的sharex
    # 開始創(chuàng)建所有的子窗口
    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開始,因?yàn)榈谝粋€(gè)在上面已經(jīng)繪制過(guò)了
        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)
    # 對(duì)比度拉伸
    p1, p2 = np.percentile(img, (0, 70))  # numpy計(jì)算多維數(shù)組的任意百分比分位數(shù)
    rescale_img = np.uint8((np.clip(img, p1, p2) - p1) / (p2 - p1) * 255)

    # 對(duì)數(shù)變換
    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])
    # 對(duì)比度自適應(yīng)直方圖均衡化
    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, morphology
import matplotlib.pyplot as plt
import numpy as np


def 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_cdf


def plot_all(images, titles, cols):
    """
    輸入titles、images、以及每一行多少列,自動(dòng)計(jì)算行數(shù)、并繪制圖像和其直方圖
    :param images:
    :param titles:
    :param cols: 每一行多少列
    :return:
    """
    fig = plt.figure(figsize=(12, 8))
    img_num = len(images)  # 圖片的個(gè)數(shù)
    rows = int(np.ceil(img_num / cols) * 2)  # 上圖下直方圖 所以一共顯示img_num*2個(gè)子圖
    axes = np.zeros((rows, cols), dtype=object)
    axes = axes.ravel()
    axes[0] = fig.add_subplot(rows, cols, 1)  # 先定義第一個(gè)img 單獨(dú)拿出來(lái)定義它是為了下面的sharex
    # 開始創(chuàng)建所有的子窗口
    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開始,因?yàn)榈谝粋€(gè)在上面已經(jīng)繪制過(guò)了
        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)
    # 對(duì)比度拉伸
    p1, p2 = np.percentile(img, (0, 70))  # numpy計(jì)算多維數(shù)組的任意百分比分位數(shù)
    rescale_img = exposure.rescale_intensity(img, in_range=(p1, p2))

    # 對(duì)數(shù)變換
    # 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])

    # 對(duì)比度自適應(yīng)直方圖均衡化
    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解決彩色圖亮度不均衡問(wèn)題的詳細(xì)內(nèi)容,更多關(guān)于Python OpenCV彩色圖亮度不均衡的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python3實(shí)現(xiàn)的字典遍歷操作詳解

    Python3實(shí)現(xiàn)的字典遍歷操作詳解

    這篇文章主要介紹了Python3實(shí)現(xiàn)的字典遍歷操作,結(jié)合實(shí)例形式分析了Python3針對(duì)字典鍵、鍵值及鍵值對(duì)遍歷的相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • python實(shí)現(xiàn)Flappy Bird源碼

    python實(shí)現(xiàn)Flappy Bird源碼

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)Flappy Bird源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Python用Try語(yǔ)句捕獲異常的實(shí)例方法

    Python用Try語(yǔ)句捕獲異常的實(shí)例方法

    在本篇文章中小編給大家整理了關(guān)于Python用Try語(yǔ)句如何捕獲異常的相關(guān)知識(shí)點(diǎn)內(nèi)容,需要的朋友們參考下。
    2019-06-06
  • python 實(shí)現(xiàn)將小圖片放到另一個(gè)較大的白色或黑色背景圖片中

    python 實(shí)現(xiàn)將小圖片放到另一個(gè)較大的白色或黑色背景圖片中

    今天小編就為大家分享一篇python 實(shí)現(xiàn)將小圖片放到另一個(gè)較大的白色或黑色背景圖片中,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • python類名和類方法cls修改類變量的值

    python類名和類方法cls修改類變量的值

    這篇文章主要介紹了python類名和類方法cls修改類變量的值,通過(guò)類對(duì)象是無(wú)法修改類變量的值的,本質(zhì)其實(shí)是給類對(duì)象新添加?name?和?age?變量,下文更多的相關(guān)介紹需要的小伙伴可任意參考一下
    2022-04-04
  • Python Beautiful Soup模塊使用教程詳解

    Python Beautiful Soup模塊使用教程詳解

    Beautiful Soup 簡(jiǎn)稱 BS4(其中 4 表示版本號(hào))是一個(gè) Python 中常用的頁(yè)面解析庫(kù),它可以從 HTML 或 XML 文檔中快速地提取指定的數(shù)據(jù),這篇文章主要介紹了Python Beautiful Soup模塊的使用
    2023-02-02
  • 利用Python進(jìn)行數(shù)據(jù)清洗的操作指南

    利用Python進(jìn)行數(shù)據(jù)清洗的操作指南

    數(shù)據(jù)清洗是指發(fā)現(xiàn)并糾正數(shù)據(jù)文件中可識(shí)別的錯(cuò)誤的最后一道程序,包括檢查數(shù)據(jù)一致性,處理無(wú)效值和缺失值等。本文為大家介紹了Python進(jìn)行數(shù)據(jù)清洗的操作詳解,需要的可以參考一下
    2022-03-03
  • Python實(shí)現(xiàn)圖像的垂直投影示例

    Python實(shí)現(xiàn)圖像的垂直投影示例

    今天小編就為大家分享一篇Python實(shí)現(xiàn)圖像的垂直投影示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • Python項(xiàng)目管理工具Rye的工作原理

    Python項(xiàng)目管理工具Rye的工作原理

    在開發(fā)Python項(xiàng)目時(shí),有時(shí)會(huì)在一臺(tái)電腦上,同時(shí)存在多個(gè)python項(xiàng)目,而且每個(gè)項(xiàng)目的python版本和依賴可能都不一樣,此時(shí)需要使用python項(xiàng)目管理工具來(lái)進(jìn)行管理,rye是一個(gè)python項(xiàng)目管理工具,本文簡(jiǎn)單介紹rye的工作原理
    2023-07-07
  • Python文件處理、os模塊、glob模塊

    Python文件處理、os模塊、glob模塊

    這篇文章介紹了Python處理文件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05

最新評(píng)論