欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

opencv-python圖像增強(qiáng)解讀

 更新時(shí)間:2023年05月09日 10:22:31   作者:__JDM__  
這篇文章主要介紹了opencv-python圖像增強(qiáng)解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

圖像增強(qiáng)算子

幾何變換算子

? 圖像的幾何變換又稱為圖像空間變換, 它將一幅圖像中的坐標(biāo)位置映射到另一幅圖像中的新坐標(biāo)位置。

  • 圖像縮放

縮放只是調(diào)整圖像的大小。為此,OpenCV 附帶了一個(gè)函數(shù)cv.resize()。圖像的大小可以手動(dòng)指定,也可以指定縮放因子,使用了不同 的插值方法。

首選的插值方法是cv2.INTER_AREA 用于縮小,cv.INTER_CUBIC(慢)和cv.INTER_LINEAR 用于縮放。

默認(rèn)情況下, 出于所有調(diào)整大小的目的,使用的插值方法為cv.INTER_LINEAR

您可以使用以下方法調(diào)整輸入圖像的大?。?/p>

  • ? INTER_AREA基于區(qū)域像素關(guān)系的一種重采樣或者插值方式.該方法是圖像抽取的首選方法,它可以產(chǎn)生更少的波紋.
  • ? INTER_LINEAR是雙線性插值,默認(rèn)情況下使用該方式進(jìn)行插值;INTER_CUBIC是用3次方函數(shù)差值.
import numpy as np
import cv2 as cv
img = cv.imread('1.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
#或者
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)
  • 圖像翻轉(zhuǎn)

?opencv翻轉(zhuǎn)圖像有三種方式,分別時(shí)上下翻轉(zhuǎn)、左右翻轉(zhuǎn)和對(duì)角線翻轉(zhuǎn)。

import cv2 as cv
import numpy as np
img = cv.imread(image_path, cv.IMREAD_COLOR)
# 上下翻轉(zhuǎn)
dst1 = cv.flip(img, 0)
res1 = np.vstack((img, dst1))
# 左右翻轉(zhuǎn)
dst2 = cv.flip(img, 1)
res2 = np.vstack((img, dst2))
# 對(duì)角線翻轉(zhuǎn)
dst3 = cv.flip(img, -1)
res3 = np.vstack((img, dst3))
  • 仿射變換

?仿射變換基本上是兩個(gè)圖像之間的關(guān)系。使用矩陣乘法(線性變換)的形式表示的轉(zhuǎn)換,后跟向量加法(轉(zhuǎn)換)關(guān)于這種關(guān)系的信息大概可以通過兩種方式來實(shí)現(xiàn):

  • 1.我們知道X和T我們也知道它們是相關(guān)的。那么我們的任務(wù)就是找M
  • 2.我們知道M和X。為了獲得T,我們只需要計(jì)算T= M⋅ X。其中M的是確定的,或者它可以作為點(diǎn)之間的幾何關(guān)系。

在OpenCV中,仿射變換可以通過函數(shù)warpAffine來支持,當(dāng)然部分單獨(dú)的函數(shù)也可以進(jìn)行某個(gè)特定的變換,如縮放和旋轉(zhuǎn)就有單獨(dú)的變換函數(shù)。

img=cv2.imread('yun.jpg',cv2.IMREAD_GRAYSCALE)
cv2.imwrite('yun.jpg',img)
#原圖的寬高
h,w=img.shape[:2]
#仿射變換矩陣 縮小2倍
A1=np.array([[0.5,0,0],[0,0.5,0]],np.float32)
A2=cv2.warpAffine(img,A1,(w,h),borderValue=126)
#縮小后平移
B1=np.array([[0.5,0,w/4],[0,0.5,h/4]],np.float32)
B2=cv2.warpAffine(img,B1,(w,h),borderValue=126)
#使圖像旋轉(zhuǎn)
C1=cv2.getRotationMatrix2D((w/2.0,h/2.0),30,1)
C2=cv2.warpAffine(img,C1,(w,h),borderValue=126)

圖像金字塔算子

它的本質(zhì)是對(duì)圖像進(jìn)行放縮變換。一般情況下,我們要處理是一副具有固定分辨率的圖像。

但是有些情況下,我們需要對(duì)同一圖像的不同分辨率的子圖像進(jìn)行處理。

比如,我們要在一幅圖像中查找某個(gè)目標(biāo),比如臉,我們不知道目標(biāo)在圖像中的尺寸大小。這種情況下,我們需要?jiǎng)?chuàng)建一組圖像,這些圖像是具有不同分辨率的原始圖像。

我們把這組圖像叫做圖像金字塔(簡單來說就是同一圖像的不同分辨率的子圖集合)。

如果我們把最大的圖像放在底部,最小的放在頂部,看起來像一座金字塔,故而得名圖像金字塔。

? 圖像金字塔最初用于機(jī)器視覺和圖像壓縮,一幅圖像的金字塔是一系列以金字塔形狀排列的分辨率逐步降低,且來源于同一張?jiān)紙D的圖像集合。

其通過梯次向下采樣獲得,直到達(dá)到某個(gè)終止條件才停止采樣。金字塔的底部是待處理圖像的高分辨率表示,而頂部是低分辨率的近似。我們將一層一層的圖像比喻成金字塔,層級(jí)越高,則圖像越小,分辨率越低。

  • 拉普拉斯金字塔

用來從金字塔低層圖像重建上層未采樣圖像,在數(shù)字圖像處理中也即是預(yù)測殘差,可以對(duì)圖像進(jìn)行最大程度的還原,配合高斯金字塔一起使用。

兩者的簡要區(qū)別:高斯金字塔用來向下降采樣圖像,而拉普拉斯金字塔則用來從金字塔底層圖像中向上采樣重建一個(gè)圖像。

要從金字塔第i層生成第i+1層(我們表示第i+1層為G_i+1),我們先要用高斯核對(duì)G_1進(jìn)行卷積,然后刪除所有偶數(shù)行和偶數(shù)列。

當(dāng)然的是,新得到圖像面積會(huì)變?yōu)樵磮D像的四分之一。按上述過程對(duì)輸入圖像G_0執(zhí)行操作就可產(chǎn)生出整個(gè)金字塔。

當(dāng)圖像向金字塔的上層移動(dòng)時(shí),尺寸和分辨率就降低。OpenCV中,從金字塔中上一級(jí)圖像生成下一級(jí)圖像的可以用PryDown。而通過PryUp將現(xiàn)有的圖像在每個(gè)維度都放大兩遍。

圖像金字塔中的向上和向下采樣分別通過OpenCV函數(shù) pyrUp 和 pyrDown 實(shí)現(xiàn)。

對(duì)圖像向上采樣:pyrUp函數(shù)

對(duì)圖像向下采樣:pyrDown函數(shù)

這里的向下與向上采樣,是對(duì)圖像的尺寸而言的(和金字塔的方向相反),向上就是圖像尺寸加倍,向下就是圖像尺寸減半。而如果我們按上圖中演示的金字塔方向來理解,金字塔向上圖像其實(shí)在縮小,這樣剛好是反過來了。

但需要注意的是,PryUp和PryDown不是互逆的,即PryUp不是降采樣的逆操作。這種情況下,圖像首先在每個(gè)維度上擴(kuò)大為原來的兩倍,新增的行(偶數(shù)行)以0填充。然后給指定的濾波器進(jìn)行卷積(實(shí)際上是一個(gè)在每個(gè)維度都擴(kuò)大為原來兩倍的過濾器)去估計(jì)“丟失”像素的近似值。

PryDown( )是一個(gè)會(huì)丟失信息的函數(shù)。為了恢復(fù)原來更高的分辨率的圖像,我們要獲得由降采樣操作丟失的信息,這些數(shù)據(jù)就和拉普拉斯金字塔有關(guān)系了。

import cv2 as cv
# 高斯金字塔
def pyramid_demo(image):
    level = 3  # 金字塔層數(shù)
    temp = image.copy()
    pyramid_images = []
    for i in range(level):
        dst = cv.pyrDown(temp)       # 降采樣
        pyramid_images.append(dst)   # 降采樣的結(jié)果添加進(jìn)列表
        cv.imshow('pyramid_down' + str(i), dst)   # 金字塔第幾層  imshow
        temp = dst.copy()            # 采樣的圖像又賦給temp  接著降采樣
    return pyramid_images
# 拉普拉斯金字塔
# 由高斯金字塔可以構(gòu)建拉普拉斯金字塔
def lapalian_demo(image):
    pyramid_images = pyramid_demo(image)
    level = len(pyramid_images)         # 求層數(shù)
    for i in range(level - 1, -1, -1):  # 每次遞減
        if (i - 1) < 0:
            expand = cv.pyrUp(pyramid_images[i], dstsize=image.shape[:2])  # 升采樣
            lpls = cv.subtract(image, expand)
            cv.imshow("lapalian_down" + str(i), lpls)
        else:
            expand = cv.pyrUp(pyramid_images[i], dstsize=pyramid_images[i - 1].shape[:2])
            lpls = cv.subtract(pyramid_images[i - 1], expand)
            cv.imshow("lapalian_down_" + str(i), lpls)

圖像平滑算子

在處理和傳輸數(shù)字圖像的過程中可能會(huì)受到不同的噪聲的干擾,圖像噪聲會(huì)引起圖像質(zhì)量降低、圖像變得模糊,使圖像的特征被淹沒、而通過除去噪聲來達(dá)到圖像增強(qiáng)的目的的操作被稱為圖像平滑處理

  • 均值濾波

假設(shè)被噪聲污染的數(shù)字圖像空間含有 N*N 個(gè)像素點(diǎn),而這幅數(shù)字圖像中每一個(gè)像素點(diǎn)值可以通過領(lǐng)域內(nèi)幾個(gè)像素點(diǎn)的平均值計(jì)算出來,采用平滑圖像處理方法就可以得到一幅新的圖像,這個(gè)過程就被稱為均值濾波。

import cv2
import numpy as np
#讀取圖像信息
k = 5
img0 = cv2.imread("1.jpg")
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
h, w = img0.shape[:2]
r5=cv2.blur(img1,(k,k)) #5*5卷積
  • 方框?yàn)V波

方框?yàn)V波是均值濾波的一種形式。在均值濾波中,濾波結(jié)果的像素值是任意一個(gè)點(diǎn)的鄰域平均值,等于各鄰域像素值之和的均值,而在方框?yàn)V波中,可以自由選擇是否對(duì)均值濾波的結(jié)果進(jìn)行歸一化,即可以自由選擇濾波結(jié)果是鄰域像素值之和的平均值,還是鄰域像素值之和。

import cv2
import matplotlib.pyplot as plt
# 讀取圖片
img = cv2.imread('1.jpg')
# 方框?yàn)V波,True表示歸一化,則效果與均值濾波相同。
result = cv2.boxFilter(source, -1, (5, 5), normalize=False)
# sqrBoxFilter實(shí)現(xiàn)對(duì)每個(gè)像素值的平方求和
# result1 = cv2.sqrBoxFilter(source, -1, (5, 5), normalize=True)
  • 高斯濾波

為了克服簡單局部平均法的弊端(圖像模糊),目前已提出許多保持邊緣、細(xì)節(jié)的局部平滑算法。它們的出發(fā)點(diǎn)都集中在如何選擇鄰域的大小、形狀和方向、參數(shù)加平均及鄰域各店的權(quán)重系數(shù)等。

圖像高斯平滑也是鄰域平均的思想對(duì)圖像進(jìn)行平滑的一種方法,在圖像高斯平滑中,對(duì)圖像進(jìn)行平均時(shí),不同位置的像素被賦予了不同的權(quán)重。高斯平滑與簡單平滑不同,它在對(duì)鄰域內(nèi)像素進(jìn)行平均時(shí),給予不同位置的像素不同的權(quán)值.

import cv2
k = 5
img=cv2.imread('1.jpg')
#(5, 5)表示高斯矩陣的長與寬都是5,標(biāo)準(zhǔn)差取0
blur=cv2.GaussianBlur(img,(k,k),0)
  • 中值濾波

中值濾波器遍歷信號(hào)的每個(gè)元素(在這種情況下為圖像),并用其相鄰像素的中位數(shù)(位于估計(jì)像素周圍的正方形鄰域)中替換每個(gè)像素。

import cv2
k = 5
img=cv2.imread('1.jpg')
#常用來去除椒鹽噪聲
#卷積核使用奇數(shù)
blur=cv2.medianBlur(img,k)
  • 雙邊濾波

? 雙邊濾波是一種非線性的濾波方法,是結(jié)合圖像的空間鄰近度和像素值相似度的一種折衷處理,同時(shí)考慮空間與信息和灰度相似性,達(dá)到保邊去噪的目的,具有簡單、非迭代、局部處理的特點(diǎn)。

之所以能夠達(dá)到保邊去噪的濾波效果是因?yàn)闉V波器由兩個(gè)函數(shù)構(gòu)成:一個(gè)函數(shù)是由幾何空間距離決定濾波器系數(shù),另一個(gè)是由像素差值決定濾波器系數(shù).

相對(duì)高斯濾波去降噪,會(huì)較明顯地模糊邊緣,對(duì)于高頻細(xì)節(jié)的保護(hù)效果并不明顯。

#cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])
#能在保持邊界清晰的情況下有效的去除噪音
#但是這種操作與其他濾波器相比會(huì)比較慢
import cv2
img=cv2.imread('1.jpg')
#cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)
#9 鄰域直徑,兩個(gè)75分別是空間高斯函數(shù)標(biāo)準(zhǔn)差,灰度值相似性高斯函數(shù)標(biāo)準(zhǔn)差
blur = cv2.bilateralFilter(img,9,75,75)

?參數(shù)解釋:

  • src:輸入圖像
  • d:過濾時(shí)周圍每個(gè)像素領(lǐng)域的直徑
  • sigmaColor:在color space中過濾sigma。參數(shù)越大,臨近像素將會(huì)在越遠(yuǎn)的地方mix。
  • sigmaSpace:在coordinate space中過濾sigma。參數(shù)越大,那些顏色足夠相近的的顏色的影響越大。

傅立葉變換算子

表示能將滿足一定條件的某個(gè)函數(shù)表示成三角函數(shù)(正弦和/或余弦函數(shù))或者它們的積分的線性組合。

在不同的研究領(lǐng)域,傅立葉變換具有多種不同的變體形式,如連續(xù)傅立葉變換和離散傅立葉變換。

傅里葉變換是一種分析信號(hào)的方法,它可分析信號(hào)的成分,也可用這些成分合成信號(hào)。

許多波形可作為信號(hào)的成分,比如正弦波、方波、鋸齒波等,傅里葉變換用正弦波作為信號(hào)的成分。對(duì)于圖像,將時(shí)域轉(zhuǎn)化為頻域。

  • 傅立葉變換算子

在頻域范圍內(nèi)可以研究圖像增強(qiáng),可以利用頻率成分和圖像外表之間的對(duì)應(yīng)關(guān)系。

一些在空間域表述困難的增強(qiáng)任務(wù),在頻率域中變得非常普通濾波在頻率域更為直觀,它可以解釋空間域?yàn)V波的某些性質(zhì),可以在頻率域指定濾波器,做反變換,然后在空間域使用結(jié)果濾波器作為空間域?yàn)V波器的指導(dǎo),一旦通過頻率域試驗(yàn)選擇了空間濾波,通常實(shí)施都在空間域進(jìn)行。

意義:

1、圖像的頻率是表征圖像中灰度變化劇烈程度的指標(biāo),是灰度在平面空間上的梯度**(灰度變化得快頻率就高,灰度變化得慢 頻率就低)**

? 2、圖像上某一點(diǎn)與鄰域點(diǎn)灰度值差異的強(qiáng)弱,即梯度的大小,也即該點(diǎn)的頻率的大?。ú町?梯度越大,頻率越高,能量越低, 在頻譜圖上就越暗。差異/梯度越小,頻率越低,能量越高,在頻譜圖上就越亮。換句話說,頻率譜上越亮能量越高,頻率 越低,圖像差異越小/平緩)。一般來講,梯度大則該點(diǎn)的亮度強(qiáng),否則該點(diǎn)亮度弱。頻譜圖,也叫功率圖。

#OpenCV實(shí)現(xiàn)
dft = cv2.dft(np.float32(img2), flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum1 = 20*np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121), plt.imshow(img2, cmap = 'gray')
plt.title('原圖'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum1, cmap = 'gray')
plt.title('頻譜圖'), plt.xticks([]), plt.yticks([])
plt.show()

形態(tài)學(xué)操作算子

? 形態(tài)學(xué)算子的主要思想是用一定形狀的結(jié)構(gòu)元素在圖像中抽取出相應(yīng)的某些結(jié)構(gòu),通常可以用于圖像的濾波、分割、分類等處理。形態(tài)學(xué)算子有腐蝕、膨脹、開和閉四種。

  • 圖像腐蝕

?腐蝕是一種消除邊界點(diǎn),使邊界向內(nèi)部收縮的過程??梢杂脕硐∏覠o意義的物體。腐蝕的算法: 用3x3的結(jié)構(gòu)元素,掃描圖像的每一個(gè)像素 用結(jié)構(gòu)元素與其覆蓋的二值圖像做“與”操作 如果都為1,結(jié)果圖像的該像素為1。否則為0。

結(jié)果:使二值圖像減小一圈

import cv2
img0 = cv2.imread("1.jpg")
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
erosion1 = cv2.erode(img1, kernel1)
  • 圖像膨脹

膨脹是將與物體接觸的所有背景點(diǎn)合并到該物體中,使邊界向外部擴(kuò)張的過程??梢杂脕硖钛a(bǔ)物體中的空洞。膨脹的算法: 用3x3的結(jié)構(gòu)元素,掃描圖像的每一個(gè)像素 用結(jié)構(gòu)元素與其覆蓋的二值圖像做“與”操作 如果都為0,結(jié)果圖像的該像素為0。否則為1

結(jié)果:使二值圖像擴(kuò)大一圈

import cv2
img0 = cv2.imread("1.jpg")
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
dilation1 = cv2.dilate(img1, kernel1) 
  • 開運(yùn)算

雖然腐蝕可以將粘連的目標(biāo)進(jìn)行分離,膨脹可以將斷續(xù)的目標(biāo)進(jìn)行連接,但是無論是腐蝕還是膨脹處理后,目標(biāo)的尺寸都會(huì)產(chǎn)生變化。

開運(yùn)算,閉運(yùn)算就是為了解決這個(gè)問題。

先腐蝕后膨脹的過程稱為開運(yùn)算。用來消除小物體、在纖細(xì)點(diǎn)處分離物體、平滑較大物體的邊界的同時(shí)并不明顯改變其面積。

import cv2
import numpy as np
ori = cv2.imread(r"1.jpg")
k = np.ones((10, 10), np.uint8)
opening = cv2.morphologyEx(ori, cv2.MORPH_OPEN,k)       # 開運(yùn)算
  • 閉運(yùn)算

先膨脹后腐蝕的過程稱為閉運(yùn)算。用來填充物體內(nèi)細(xì)小空洞、連接鄰近物體、平滑其邊界的同時(shí)并不明顯改變其面積。

import cv2
import numpy as np
ori = cv2.imread(r"1.jpg")
k1 = np.ones((8, 8), np.uint8)
k2 = np.ones((15, 15), np.uint8)
closing1 = cv2.morphologyEx(ori, cv2.MORPH_CLOSE, k1)
closing2 = cv2.morphologyEx(ori, cv2.MORPH_CLOSE, k2)
  • 梯度運(yùn)算

? 圖像的梯度操作就是將圖像膨脹的結(jié)果減去腐蝕的結(jié)果,以得到圖像的邊緣。

將形態(tài)學(xué)運(yùn)算函數(shù)中第二個(gè)參數(shù)改為cv2.MORPH_GRADIENT即可。

即cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel)

import cv2
import numpy as np
ori = cv2.imread(r"1.jpg")
result=cv2.morphologyEx(ori, cv2.MORPH_GRADIENT, kernel)

?

  • 禮帽運(yùn)算

禮帽操作就是用原圖減去開運(yùn)算的圖像,以得到前景圖外面的毛刺噪聲,因?yàn)殚_運(yùn)算可以消除小物體,所以通過做差就可以將消除掉的小物體提取出來,使用時(shí)修改形態(tài)學(xué)運(yùn)算函數(shù)參數(shù)為cv2.MORPH_TOPHAT即可

import cv2
import numpy as np
ori = cv2.imread(r"1.jpg")
result=cv2.morphologyEx(ori, cv2.MORPH_TOPHAT, kernel)
  • 黑帽運(yùn)算

? 黑帽就是用原圖減去閉運(yùn)算的圖像,以得到前景圖像內(nèi)部的小孔等噪聲。使用時(shí)修改形態(tài)學(xué)運(yùn)算函數(shù)參數(shù)為cv2.MORPH_BLACKHAT即可。

import cv2
import numpy as np
ori = cv2.imread(r"1.jpg")
result=cv2.morphologyEx(ori, cv2.MORPH_BLACKHAT, kernel)

直方圖均衡化

?圖像的空域處理是一種重要的圖像處理技術(shù),這類方法直接以圖像的像素操作為基礎(chǔ),主要分為灰度變換空域?yàn)V波兩大類,直方圖均衡化(Histogram equalization)就是一種常用的灰度變換方法。

? 通常,暗圖像直方圖的分量集中在灰度較低的一端,而亮圖像直方圖分量偏向于灰度較高的一端

  • 直方圖均衡化

? 可以得到這樣的結(jié)論:如果一幅圖像的灰度直方圖幾乎覆蓋了整個(gè)灰度的取值范圍,并且除了個(gè)別灰度值的個(gè)數(shù)較為突出,整個(gè)灰度值分布近似于均勻分布,那么這幅圖像就具有較大的灰度動(dòng)態(tài)范圍和較高的對(duì)比度,同時(shí)圖像的細(xì)節(jié)更為豐富。

已經(jīng)證明,僅僅依靠輸入圖像的直方圖信息,就可以得到一個(gè)變換函數(shù),利用該變換函數(shù)可以將輸入圖像達(dá)到上述效果,該過程就是直方圖均衡化。

import cv2
import numpy as np
from matplotlib import pyplot as plt
'''
calcHist-計(jì)算圖像直方圖
函數(shù)原型:calcHist(images,channels,mask,histSize,ranges,hist=None,accumulate=None)
images:圖像矩陣,例如:[image]
channels:通道數(shù),例如:0
mask:掩膜,一般為:None
histSize:直方圖大小,一般等于灰度級(jí)數(shù)
ranges:橫軸范圍
'''
# 獲取灰度圖像
img = cv2.imread("1.jpg", 0)
# 灰度圖像的直方圖
hist = cv2.calcHist([img],[0],None,[256],[0,256])
plt.figure()#新建一個(gè)圖像
plt.title("Grayscale Histogram")
plt.xlabel("Bins")#X軸標(biāo)簽
plt.ylabel("# of Pixels")#Y軸標(biāo)簽
plt.plot(hist)
plt.xlim([0,256])#設(shè)置x坐標(biāo)軸范圍
plt.show()
'''
equalizeHist—直方圖均衡化
函數(shù)原型: equalizeHist(src, dst=None)
src:圖像矩陣(單通道圖像)
dst:默認(rèn)即可
'''
# 灰度圖像直方圖均衡化
dst = cv2.equalizeHist(img)
# 直方圖
hist = cv2.calcHist([dst],[0],None,[256],[0,256])
plt.figure()
plt.hist(dst.ravel(), 256)
plt.show()
cv2.imshow("Histogram Equalization",np.hstack([img, dst]))
cv2.waitKey(0)
# 彩色圖像直方圖均衡化
img = cv2.imread("1.jpg", 1)
cv2.imshow("src", img)
# 彩色圖像均衡化,需要分解通道 對(duì)每一個(gè)通道均衡化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
# 合并每一個(gè)通道
result = cv2.merge((bH, gH, rH))
cv2.imshow("dst_rgb", result)
cv2.waitKey(0)

Gamma變換

? 伽馬變換就是用來圖像增強(qiáng),其提升了暗部細(xì)節(jié),簡單來說就是通過非線性變換,讓圖像從暴光強(qiáng)度的線性響應(yīng)變得更接近人眼感受的響應(yīng),即將漂白(相機(jī)曝光)或過暗(曝光不足)的圖片,進(jìn)行矯正。

  • gamma變換

Gamma變換是對(duì)輸入圖像灰度值進(jìn)行的非線性操作,使輸出圖像灰度值與輸入圖像灰度值呈指數(shù)關(guān)系:

這個(gè)指數(shù)即為Gamma。

經(jīng)過Gamma變換后的輸入和輸出圖像灰度值關(guān)系如圖1所示:橫坐標(biāo)是輸入灰度值,縱坐標(biāo)是輸出灰度值,藍(lán)色曲線是gamma值小于1時(shí)的輸入輸出關(guān)系,紅色曲線是gamma值大于1時(shí)的輸入輸出關(guān)系。

可以觀察到,當(dāng)gamma值小于1時(shí)(藍(lán)色曲線),圖像的整體亮度值得到提升,同時(shí)低灰度處的對(duì)比度得到增加,更利于分辯低灰度值時(shí)的圖像細(xì)節(jié)。

Gamma大于1時(shí),對(duì)圖像的灰度分布直方圖具有拉伸作用(使灰度向高灰度值延展),而小于1時(shí),對(duì)圖像的灰度分布直方圖具有收縮作用(是使灰度向低灰度值方向靠攏).

import cv2
#分道計(jì)算每個(gè)通道的直方圖
img0 = cv2.imread('12.jpg')
hist_b = cv2.calcHist([img0],[0],None,[256],[0,256])
hist_g = cv2.calcHist([img0],[1],None,[256],[0,256])
hist_r = cv2.calcHist([img0],[2],None,[256],[0,256])
def gamma_trans(img,gamma):
	#具體做法先歸一化到1,然后gamma作為指數(shù)值求出新的像素值再還原
	gamma_table = [np.power(x/255.0,gamma)*255.0 for x in range(256)]
	gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
	#實(shí)現(xiàn)映射用的是Opencv的查表函數(shù)
	return cv2.LUT(img0,gamma_table)
img0_corrted = gamma_trans(img0, 0.5)
cv2.imshow('img0',img0)
cv2.imshow('gamma_image',img0_corrted)
cv2.imwrite('gamma_image.png',img0_corrted)
#分通道計(jì)算Gamma校正后的直方圖
hist_b_c =cv2.calcHist([img0_corrted],[0],None,[256],[0,256])
hist_g_c =cv2.calcHist([img0_corrted],[1],None,[256],[0,256])
hist_r_c =cv2.calcHist([img0_corrted],[2],None,[256],[0,256])
fig = plt.figure('gamma')
pix_hists = [[hist_b, hist_g, hist_r],
    [hist_b_c, hist_g_c, hist_r_c]]
pix_vals = range(256)
for sub_plt, pix_hist in zip([121, 122], pix_hists):
	ax = fig.add_subplot(sub_plt, projection='3d')
	for c, z, channel_hist in zip(['b', 'g', 'r'], [20, 10, 0], pix_hist):
  		cs = [c] * 256
  		ax.bar(pix_vals, channel_hist, zs=z, zdir='y', color=cs, alpha=0.618, edgecolor='none', lw=0)
	ax.set_xlabel('Pixel Values')
	ax.set_xlim([0, 256])
	ax.set_ylabel('Count')
	ax.set_zlabel('Channels')
plt.show()
cv2.waitKey()

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論