대학원 일기

White Channel Prior 코드 구현 본문

Paper/Paper codes

White Channel Prior 코드 구현

대학원생(노예) 2022. 2. 24. 01:14

White Channel Prior

  White Channel Prior(이하 WCP)는 이전글인 Dark Channel Prior(이하 DCP)를 활용하여 발전된 단일 이미지 안개제거 기법이다. DCP의 기반이 되는 R, G, B 채널 중 한 채널은 안개가 제거된 영상에서 낮은 수치를 갖는다는 점을 보고, WCP는 DCP 알고리즘을 통해 얻은 깨끗한 영상에서 R, G, B 세 채널 중에서 적어도 한 채널의 명도 값이 255에 가까운 경향을 가질 것이라고 예상하여 DCP 알고리즘과 반대로 R, G, B 값들 중 최댓값을 찾아 WCP 알고리즘을 돌려 안개가 제거된 영상을 얻는다. 아래 사진은 WCP 알고리즘 순서도이다.

Code

import os
import cv2
import math
import numpy as np

# DCP
def DarkChannel(img,size):
    b,g,r = cv2.split(img) 
    dark_channel = cv2.min(cv2.min(r,g),b)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(size,size))
    dark = cv2.erode(dark_channel, kernel)
    return dark

# WCP
def WhiteChannel(img, size):
    b, g, r = cv2.split(img)
    white_channel = cv2.max(cv2.max(r, g), b)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (size, size))
    white = cv2.erode(white_channel, kernel)
    return white

def AtmLight(img, dark):
    [h, w] = img.shape[:2]
    img_size = h*w
    numpx = int(max(math.floor(img_size/1000), 1))
    darkvec = dark.reshape(img_size)
    imgvec = img.reshape(img_size, 3)

    indices = darkvec.argsort()
    indices = indices[img_size-numpx::]

    atmsum = np.zeros([1, 3])
    for ind in range(1, numpx):
       atmsum = atmsum + imgvec[indices[ind]]

    A = atmsum / numpx
    return A

# Estimate Transmission
def TransmissionEstimateDark(img, A, size):
    omega = 0.95
    im3 = np.empty(img.shape,img.dtype)

    for ind in range(0,3):
        im3[:,:,ind] = img[:,:,ind]/A[0,ind]

    transmission = 1 - omega*DarkChannel(im3,size)
    return transmission

# Re-Estimate Transmission
def TransmissionEstimateWhite(img, A, size):
    omega = 0.95
    im3 = np.empty(img.shape, img.dtype)

    for ind in range(0, 3):
        im3[:, :, ind] = img[:, :, ind]/A[0, ind]

    transmission_white = 1 - omega*WhiteChannel(im3, size)
    return transmission_white

# Guided Filter
def TransmissionRefine(img, et):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = np.float64(gray)/255
    r = 60
    eps = 0.0001
    t = Guidedfilter(gray, et, r, eps)

    return t

def Guidedfilter(image, p, r, eps): # Haze image(Guide, I), transmission(input), kernel size, strength
    blur_factor = (r, r)
    # cv2.blur(src, kernel size)
    mean_I = cv2.blur(image, blur_factor) # I blurring
    mean_p = cv2.blur(p, blur_factor) # p blurring
    corr_I = cv2.blur(image*image, blur_factor) # I * I blurring
    corr_Ip = cv2.blur(image*p, blur_factor) # I * p blurring
    
    var_I = corr_I - mean_I * mean_I # variance
    cov_Ip = corr_Ip - mean_I * mean_p # covariance

    a = cov_Ip / (var_I + eps)
    b = mean_p - a * mean_I

    mean_a = cv2.blur(a, blur_factor)
    mean_b = cv2.blur(b, blur_factor)

    q = mean_a * image + mean_b # linear transformation: q = a*I + b 
    return q

def Recover(img, t, A, tx=0.1):
    res = np.empty(img.shape, img.dtype)
    t = cv2.max(t, tx)

    for ind in range(0, 3):
        res[:, :, ind] = (img[:, :, ind]-A[0, ind])/t + A[0, ind]

    return res

def Opening(img):
    kernel = np.ones((2, 2), np.uint8)
    res = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
    return res

path = os.path.join('./image/Haze.jpg')
src = cv2.imread(path)
I = src.astype('float64')/255

# DCP 기법
dark = DarkChannel(I, 15)
A = AtmLight(I, dark)
te = TransmissionEstimateDark(I, A, 15)
t = TransmissionRefine(src, te)
J = Recover(I, t, A, 0.1)

# WCP 기법
white = WhiteChannel(J, 15)
A_white = AtmLight(I, white)
te_white = TransmissionEstimateWhite(I, A_white, 15)
t_white = TransmissionRefine(src, te_white)
J_white = Recover(I, t_white, A_white, 0.1)
Opening_white = Opening(J_white)

cv2.imshow('Original', src)
cv2.imshow('DCP: Dehaze image', J)
cv2.imshow('WCP: Dehaze image', J_white)
cv2.imshow('Opening WCP: Dehaze image', Opening_white)

cv2.imwrite("White channel prior/output/WCP_transmission.jpg", t_white*255)
cv2.imwrite("White channel prior/output/Haze.jpg", I*255)
cv2.imwrite("White channel prior/output/WCP_Dehaze.jpg", J_white*255)
cv2.imwrite("White channel prior/output/DCP_Dehaze.jpg", J*255)
cv2.waitKey()

 

구현 결과

안개영상
DCP 적용한 안개제거 영상

WCP 적용한 안개제거 영상

 

Reference

https://www.kci.go.kr/kciportal/ci/sereArticleSearch/ciSereArtiView.kci?sereArticleSearchBean.artiId=ART002781555 

 

White Channel Prior: 개선된 Dark Channel Prior를 이용한 안개 제거 연구

This paper proposes a new dehaze method to improve the contrast value and color intensity degradation of the result image that occurs when the haze is removed through Dark Channel Prior, a representative algorithm of the prior based dehaze method. Due to t

www.kci.go.kr

'Paper > Paper codes' 카테고리의 다른 글

Color Attenuation Prior 코드 구현  (1) 2022.04.02
Dark Channel Prior 코드 구현  (0) 2022.02.23
Comments