일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 파이썬
- 인공지능
- 로스트아크
- 디자인패턴
- 대학원 월급
- 인공지능 깃 버전관리
- 자바 영화 api
- API
- 딥러닝 실험 깃 버전관리
- 백준
- 파이썬 경사하강법
- pandas
- 코딩테스트
- 머신러닝
- Dehaze
- MLP
- 대학원 급여
- 영화 api
- 디자인 패턴
- 의료 ai 대학원 월급
- 경사하강법
- 정규화
- 활성화 함수
- 자바
- python
- C# 프로젝트
- 자바 프로젝트
- DCP
- 딥러닝
- 통계학
- Today
- Total
대학원 일기
Dark Channel Prior 코드 구현 본문
Dark Channel Prior
Dark Channel Prior(이하 DCP)는 단일 이미지 안개제거 기법으로 2009년에 "Single image haze removal using dark channel prior"라는 논문으로 발표되었다. DCP는 안개가 제거된 영상에서 빛의 3원색인 R, G, B 값 중 한 채널이 낮은 수치를 가진다는 통계적 특성으로 이를 활용하여 안개를 제거한다. DCP의 안개제거식은 다음과 같다.
위 식에서 $I(x)$는 안개 영상이고, $J(x)$는 맑은 영상이고, $A$는 안개값(안개가 있는 정도)이다. $e^{-\beta d(x)}$는 빛이 전달되는 양이고, $\beta$는 대기산란계수, $d(x)$는 깊이 정보이다. DCP는 위 식을 기반으로 하여 안개가 제거된 영상을 얻는다.
DCP 코드
import os
import cv2
import math
import numpy as np
# https://github.com/He-Zhang/image_dehaze/blob/master/dehaze.py
# Defined Dark Channel
def DarkChannel(img, size): # img: Haze image, size: kernel size
b, g, r = cv2.split(img)
dark_channel = cv2.min(cv2.min(r, g), b) # r,g,b 채널 중 최소값(dark channel)
# 안개가 제거된 영상에서 r,g,b 중 한 채널은 낮은 값을 가짐
# cv2.getStructuringElement: 커널과 같은 역할을 하는 구조화 요소, cv2.MORPH_RECT: 직사각형 커널 모양
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (size, size))
# 침식(Erosion): 기존 객체의 영역을 깎아 내는 연산으로 객체 크기가 감소
dark = cv2.erode(dark_channel, kernel)
return dark
# Estimate AtmLight(안개값 추정)
# Automatically estimate the atmospheric lights
def AtmLight(img, dark):
'''
1. dark channel에서 가장 밝은 0.1%의 픽셀을 선택(Haze 농도 심한 곳)
2. 선택한 픽셀 위치에서 input image(I) 중 명도(intensity)가 가장 높은 화소를 Atmospheric light로 선택
-> 이를 automatically method 라고 함.
'''
[h, w] = img.shape[:2]
img_size = h*w
numpx = int(max(math.floor(img_size/1000), 1))
# Vector data(1d)
darkvec = dark.reshape(img_size)
imgvec = img.reshape(img_size, 3)
indices = darkvec.argsort()
indices = indices[img_size-numpx::]
atmsum = np.zeros([1, 3]) # r,g,b channel
for ind in range(0, numpx):
atmsum = atmsum + imgvec[indices[ind]]
A = atmsum / numpx
return A
# Estimate Transmission(전달량 추정)
def TransmissionEstimate(img, A, size): # Haze image, 안개값, kernel size
omega = 0.95 # 약간의 haze는 남겨야 함(논문 왈: 안개가 너무 완벽히 제거되면 어색하다)
im3 = np.empty(img.shape, img.dtype)
for ind in range(0, 3):
im3[:, :, ind] = img[:, :, ind]/A[0, ind] # t = min_c(min_om(Haze image / A))
transmission = 1 - omega*DarkChannel(im3, size)
return transmission
def TransmissionRefine(img, et): # Haze image, transmission
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float64(gray)/255
# Guided Filter
r = 60 # patch size
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)
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
return q
def Recover(img, t, A, tx=0.1): # Haze image, transmission, A, tx(A small certain amount of haze are preserved in very dense haze regions)
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
path = os.path.join('./image/mountains.jpg')
src = cv2.resize(cv2.imread(path), dsize=(0,0), fx=0.5, fy=0.5)
I = src.astype('float64')/255
dark = DarkChannel(I, 15)
A = AtmLight(I, dark)
te = TransmissionEstimate(I, A, 15)
t = TransmissionRefine(src, te) # Guieded Filter
J = Recover(I, t, A, 0.1)
cv2.imshow("Dark", dark)
cv2.imshow("Transmission", te)
cv2.imshow("Refine transmission", t)
cv2.imshow('Original', src)
cv2.imshow('Dehaze image', J)
cv2.imwrite("Dark channel prior/output/Haze.jpg", I*255)
cv2.imwrite("Dark channel prior/output/Dark channel.jpg", dark*255)
cv2.imwrite("Dark channel prior/output/DCP_transmission.jpg", te*255)
cv2.imwrite("Dark channel prior/output/DCP_Refined_transmission.jpg", t*255)
cv2.imwrite("Dark channel prior/output/DCP_Dehaze.jpg", J*255)
cv2.waitKey()
결과: 안개 이미지에 DCP 적용
안개 이미지![]() |
안개 제거 이미지![]() |
Dark channel![]() |
transmission![]() |
Reference
https://github.com/He-Zhang/image_dehaze
https://ieeexplore.ieee.org/document/5206515
Single image haze removal using dark channel prior
In this paper, we propose a simple but effective image prior - dark channel prior to remove haze from a single input image. The dark channel prior is a kind of statistics of the haze-free outdoor images. It is based on a key observation - most local patche
ieeexplore.ieee.org
'Paper > Paper codes' 카테고리의 다른 글
Color Attenuation Prior 코드 구현 (0) | 2022.04.02 |
---|---|
White Channel Prior 코드 구현 (0) | 2022.02.24 |