LoginSignup
0
0

【TouchDesigner】かすみ除去フィルター

Posted at

なんぞや

かすみ除去フィルターについて

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

結果

image.png

OpenCVを使ってるので30fpsくらいしか出ず却下となり、最終的に目合わせで作ったLUT(Davinciでトーンカーブと彩度の調整したもの)をあてました。
チーン。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0