なんぞや
かすみ除去フィルターについて
Lightroomやスマホの画像編集にある処理で、英語だとDehaze Filter
というらしいです。
「コントラストをあげたいけど白と黒が潰れないようにしたい」という話の流れで実装することになりました。
鮮鋭化フィルターともいうのも候補に上がりましたが、かすみ除去の処理について書きます。
実装
とりあえず時間がなかったので、OpenCV
を使ったかすみ除去の処理を見つけてそれをScript TOP
に移植しました。
import cv2
import math
import numpy as np
# Dehaze Filter
# https://github.com/He-Zhang/image_dehaze/blob/master/dehaze.py
def DarkChannel(im,sz):
b,g,r = cv2.split(im)
dc = cv2.min(cv2.min(r,g),b)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(sz,sz))
dark = cv2.erode(dc,kernel)
return dark
def AtmLight(im,dark):
[h,w] = im.shape[:2]
imsz = h*w
numpx = int(max(math.floor(imsz/1000),1))
darkvec = dark.reshape(imsz)
imvec = im.reshape(imsz,3)
indices = darkvec.argsort()
indices = indices[imsz-numpx::]
atmsum = np.zeros([1,3])
for ind in range(1,numpx):
atmsum = atmsum + imvec[indices[ind]]
A = atmsum / numpx
return A
def TransmissionEstimate(im,A,sz):
omega = 0.95
im3 = np.empty(im.shape,im.dtype)
for ind in range(0,3):
im3[:,:,ind] = im[:,:,ind]/A[0,ind]
transmission = 1 - omega*DarkChannel(im3,sz)
return transmission
def Guidedfilter(im,p,r,eps):
mean_I = cv2.boxFilter(im,cv2.CV_64F,(r,r))
mean_p = cv2.boxFilter(p, cv2.CV_64F,(r,r))
mean_Ip = cv2.boxFilter(im*p,cv2.CV_64F,(r,r))
cov_Ip = mean_Ip - mean_I*mean_p
mean_II = cv2.boxFilter(im*im,cv2.CV_64F,(r,r))
var_I = mean_II - mean_I*mean_I
a = cov_Ip/(var_I + eps)
b = mean_p - a*mean_I
mean_a = cv2.boxFilter(a,cv2.CV_64F,(r,r))
mean_b = cv2.boxFilter(b,cv2.CV_64F,(r,r))
q = mean_a*im + mean_b
return q
def TransmissionRefine(im,et):
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
gray = np.float64(gray)/255
r = 60
eps = 0.0001
t = Guidedfilter(gray,et,r,eps)
return t
def Recover(im,t,A,tx = 0.1):
res = np.empty(im.shape,im.dtype)
t = cv2.max(t,tx)
for ind in range(0,3):
res[:,:,ind] = (im[:,:,ind]-A[0,ind])/t + A[0,ind]
return res
# press 'Setup Parameters' in the OP to call this function to re-create the parameters.
def onSetupParameters(scriptOp):
return
# called whenever custom pulse parameter is pushed
def onPulse(par):
return
def onCook(scriptOp):
src = scriptOp.inputs[0].numpyArray(delayed=True)
I = src.astype('float32')
I = cv2.cvtColor(I, cv2.COLOR_RGBA2BGR)
dark = DarkChannel(I,15)
A = AtmLight(I,dark)
te = TransmissionEstimate(I,A,15)
t = TransmissionRefine(src,te)
J = Recover(I,t,A,0.1)
J = cv2.cvtColor(J, cv2.COLOR_BGR2RGBA)
scriptOp.copyNumpyArray(J)
return
結果
OpenCV
を使ってるので30fps
くらいしか出ず却下となり、最終的に目合わせで作ったLUT(Davinciでトーンカーブと彩度の調整したもの)をあてました。
チーン。