您當前的位置:首頁 > 攝影

影象增強(一)ACE增強

作者:由 hh zz 發表于 攝影時間:2019-02-25

在影象增強方向上,傳統存在兩種方法一種是:Adaptive Contrast Enhancement,即自適應對比度增強,還有一種是AHE(Adaptive histgram equalization)。

AHE

是透過對區域性區域執行響應的直方圖變換,對於那些畫素值分佈比較均勻的影象來說畫素很好,然後,如果影象中包括明顯比其他區域陰暗或者亮的部分,在這些部分的對比度就得不到有效增強。

AHE的屬性:

領域的大小是該方法的一個引數。領域小,對比度得到增強,領域大,則對比度降低。

當某個領域包含的畫素值非常相似,其直方圖就會尖狀化,此時直方圖的變換會將一個很窄範圍內的畫素對映到整個畫素範圍。這些使得某些平坦區域的少量噪音經AHE處理後會放大。

還有一個

CLAHE

(Contrast Limited Adaptive Histgram equalization)

結果:

影象增強(一)ACE增強

影象增強(一)ACE增強

上述部分參考:

這裡推薦下他的cnblogs,很強的大佬%%%:

ACE

演算法源自retinex演算法,可以調整影象的對比度,實現人眼色彩的恆常性好和亮度恆常性。透過差分計算目標點與周圍畫素點的相對陰暗關係來矯正最終畫素值,有很好的增強效果,但是計算複雜讀非常高,本文提出一種有效一種非常有效的快速實現方法。

這個方法在開源軟體GIMP已經嵌入了。

影象增強(一)ACE增強

假定:x(i,j)是影象中某點的灰度值,區域性區域的定義為:以(i,j)為中心,視窗大小為(2n+1)*(2n+1)的區域,其中n為一整數。區域性的平均值,也就是低頻部分,可以用下式計算:

影象增強(一)ACE增強

而區域性方差為:

影象增強(一)ACE增強

上述式子中

\sigma^2_{x}(i,j)

就是所謂的區域性標準差(LSD)。定義f(i,j)表示x(i,j)對應的增強後的畫素值。則ACE演算法可以表示如下:

影象增強(一)ACE增強

其中G(i,j)就是上文所講的CG,一般情況下CG總是大於1的,這樣高頻成分[x(i,j)-m(i,j)]就能得到增強。

還有一種增強方式:

增強影象 = 模糊影象 + Amount *(原始影象 - 模糊影象)。

這裡的模糊影象可以用高斯模糊,也可以採用雙邊濾波器來處理,用雙邊濾波器效果要好。

python程式碼:

import cv2

import numpy as np

import math

def stretchImage(data, s=0。005, bins = 2000): #線性拉伸,去掉最大最小0。5%的畫素值,然後線性拉伸至[0,1]

ht = np。histogram(data, bins);

d = np。cumsum(ht[0])/float(data。size)

lmin = 0; lmax=bins-1

while lmin

if d[lmin]>=s:

break

lmin+=1

while lmax>=0:

if d[lmax]<=1-s:

break

lmax-=1

return np。clip((data-ht[1][lmin])/(ht[1][lmax]-ht[1][lmin]), 0,1)

g_para = {}

def getPara(radius = 5): #根據半徑計算權重引數矩陣

global g_para

m = g_para。get(radius, None)

if m is not None:

return m

size = radius*2+1

m = np。zeros((size, size))

for h in range(-radius, radius+1):

for w in range(-radius, radius+1):

if h==0 and w==0:

continue

m[radius+h, radius+w] = 1。0/math。sqrt(h**2+w**2)

m /= m。sum()

g_para[radius] = m

return m

def zmIce(I, ratio=4, radius=300): #常規的ACE實現

para = getPara(radius)

height,width = I。shape

zh,zw = [0]*radius + range(height) + [height-1]*radius, [0]*radius + range(width) + [width -1]*radius

Z = I[np。ix_(zh, zw)]

res = np。zeros(I。shape)

for h in range(radius*2+1):

for w in range(radius*2+1):

if para[h][w] == 0:

continue

res += (para[h][w] * np。clip((I-Z[h:h+height, w:w+width])*ratio, -1, 1))

return res

def zmIceFast(I, ratio, radius): #單通道ACE快速增強實現

height, width = I。shape[:2]

if min(height, width) <=2:

return np。zeros(I。shape)+0。5

Rs = cv2。resize(I, ((width+1)/2, (height+1)/2))

Rf = zmIceFast(Rs, ratio, radius) #遞迴呼叫

Rf = cv2。resize(Rf, (width, height))

Rs = cv2。resize(Rs, (width, height))

return Rf+zmIce(I,ratio, radius)-zmIce(Rs,ratio,radius)

def zmIceColor(I, ratio=4, radius=3): #rgb三通道分別增強,ratio是對比度增強因子,radius是卷積模板半徑

res = np。zeros(I。shape)

for k in range(3):

res[:,:,k] = stretchImage(zmIceFast(I[:,:,k], ratio, radius))

return res

if __name__ == ‘__main__’:

m = zmIceColor(cv2。imread(‘p4。bmp’)/255。0)*255

cv2。imwrite(‘zmIce。jpg’, m)

C++版本程式碼:

//ace 自適應對比度均衡研究

//by jsxyhelu

//感謝 imageshop

#include

“stdafx。h”

#include

#include

“opencv2/core/core。hpp”

#include

“opencv2/highgui/highgui。hpp”

#include

“opencv2/imgproc/imgproc。hpp”

using

namespace

std

using

namespace

cv

//點乘法 elementWiseMultiplication

cv

::

Mat

EWM

cv

::

Mat

m1

cv

::

Mat

m2

){

Mat

dst

=

m1

mul

m2

);

return

dst

}

//影象區域性對比度增強演算法

cv

::

Mat

ACE

cv

::

Mat

src

int

C

=

4

int

n

=

20

int

MaxCG

=

5

){

Mat

meanMask

Mat

varMask

Mat

meanGlobal

Mat

varGlobal

Mat

dst

Mat

tmp

Mat

tmp2

blur

src

clone

(),

meanMask

Size

50

50

));

//meanMask為區域性均值

tmp

=

src

-

meanMask

varMask

=

EWM

tmp

tmp

);

blur

varMask

varMask

Size

50

50

));

//varMask為區域性方差

//換算成區域性標準差

varMask

convertTo

varMask

CV_32F

);

for

int

i

=

0

i

<

varMask

rows

i

++

){

for

int

j

=

0

j

<

varMask

cols

j

++

){

varMask

at

<

float

>

i

j

=

float

sqrt

varMask

at

<

float

>

i

j

));

}

}

meanStdDev

src

meanGlobal

varGlobal

);

//meanGlobal為全域性均值 varGlobal為全域性標準差

tmp2

=

varGlobal

/

varMask

for

int

i

=

0

i

<

tmp2

rows

i

++

){

for

int

j

=

0

j

<

tmp2

cols

j

++

){

if

tmp2

at

<

float

>

i

j

>

MaxCG

){

tmp2

at

<

float

>

i

j

=

MaxCG

}

}

}

tmp2

convertTo

tmp2

CV_8U

);

tmp2

=

EWM

tmp2

tmp

);

dst

=

meanMask

+

tmp2

imshow

“D方法”

dst

);

dst

=

meanMask

+

C

*

tmp

imshow

“C方法”

dst

);

return

dst

}

void

main

()

{

Mat

src

=

imread

“plant。bmp”

0

);

imshow

“src”

src

);

ACE

src

);

waitKey

();

}

參考文獻:

由Photoshop高反差保留演算法原理聯想到的一些影象增強演算法。 - Imageshop - 部落格園

標簽: Radius  varMask  tmp2  np  ratio