사진 표현으로서의 쿠와하라 필터의 제안

소개



쿠와하라 필터란?
위의 일 에서 구와하라 필터에 대해 설명하고 있으므로 참조하십시오.

이번에는



이번에는 상기 일의 끝에 살짝 제안했다,

"심도 맵을 준비하고 그에 따라 정사각형 영역의 크기를 조정하면 재미있을지도…"

실제로 해보고 싶습니다.

이 발상은 전회의, 정사각형 영역의 한변이 일정하게 필터링한 화상에 대해서, 메인의 피사체가 분명하지 않다(어디에도 초점이 맞지 않는) 상태라면, 회화라고 하는 것보다는 배경에 보인다고 하는 의견 을 바탕으로 얻은 것입니다.

구현



전회의 기사에 대해서, 코드의 의미를 이해할 수 없는(어려움)이라고 하는 의견도 보였으므로, 계산 속도도 외시의 "그 만마"코드로 썼습니다.
하지만 파이썬에 너무 많은 양의 루프를 그대로 두는 것은 실행 시간이 힘들어지기 때문에 JITコンパイラ에 힘을 빌렸습니다.
Numba(JIT를 포함한 라이브러리)가 들어 있지 않은 사람은 JIT 컴파일러 라이브러리 Numba를 사용하여 파이썬 코드를 극적으로 가속화하는 방법 등을 참고하십시오.

Kuwahara_with_Depth.py
import matplotlib.pyplot as plt
import numpy as np
import cv2
from numba import jit


@jit
def mean(arr):
    h, w, c = arr.shape
    avg = np.array([0]*c)
    for i in range(h):
        for j in range(w):
            for k in range(c):
                avg[k] += arr[i, j, k]
    return avg/(h*w)


@jit
def var(arr, mean):
    h, w, c = arr.shape
    vari = 0
    for i in range(h):
        for j in range(w):
            for k in range(c):
                vari += (arr[i, j, k]-mean[k])**2
    return vari


@jit
def kuwahara_with_depth(pic, r, r_min, depth):
    h, w, c = pic.shape
    out = np.empty_like(pic)
    pic = np.pad(pic, ((r, r), (r, r), (0, 0)), "edge")
    depth = depth/depth.max()
    surr = ((1, 0), (0, 1), (1, 1))
    for i in range(h):
        for j in range(w):
            dr = int(depth[i, j]*(r-r_min))+r_min
            arr = pic[i+r-dr:i+r, j+r-dr:j+r]
            avg = mean(arr)
            var_min = var(arr, avg)
            color = avg
            for s, t in surr:
                arr = pic[i+r-(1-s)*dr:i+r+s*dr, j+r-(1-t)*dr:j+r+t*dr]
                avg = mean(arr)
                vari = var(arr, avg)
                if vari < var_min:
                    color = avg
                    var_min = vari
            out[i, j] = color
    return out


def main(picpath, r, r_min, rate, depthpath): #入力画像のパス、正方形領域の一辺の最大値、正方形領域の一辺の最小値、画像サイズの縮小率、深度マップのパス
    pic = np.array(plt.imread(picpath))
    pic = cv2.resize(pic, (int(pic.shape[1]*rate), int(pic.shape[0]*rate)))
    depth = cv2.resize(np.array(plt.imread(depthpath)[:, :, 0]), (pic.shape[1], pic.shape[0]))
    # depth=cv2.resize(np.rot90(np.array(plt.imread(depthpath))[:,:,0]),(pic.shape[1],pic.shape[0])) #深度マップの向きが元画像と合っていない時用
    fpic = kuwahara_with_depth(pic, r, r_min, depth).astype(pic.dtype)
    plt.imshow(fpic)
    # plt.imshow(np.rot90(fpic,3)) #出力画像が横を向いてしまっている時用
    plt.show()


picpath = "input_pic.jpg" #入力画像のパス
depthpath = "depthmap.jpg" #深度マップ画像のパス

if __name__ == "__main__":
    main(picpath, 20, 3, 0.5, depthpath)


결과



이번에도 프랑스 사진에서 프렌치 고양이를 샘플에 사용합니다.
상기까지의 설명에서는 깊이 맵이라고 표현하고 있었습니다만, 당연히 그런 데이터는 없기 때문에 어떠한 방법으로 그러한 이미지를 만듭니다. 이번에는 포토쇼에서 적당히 만들었습니다. 덧붙여서 하얗을수록 정사각형 영역의 한 변은 커집니다.
(일부 배경 흐림을 사용할 수 있는 스마트폰 사진 파일에는 심도 맵 정보가 포함되어 있는 것 같습니다. Google Camera Deph map을 사용하여 스테레오 이미지/다시점 이미지 만들기 )



이것들을 이용해 이번 필터를 걸은 것이 이쪽입니다. 꼭 클릭하여 확대해 보세요.

사진과 그림이 자연스럽게 융합할 수 있는 렌즈의 노망 대신에 페인트로 흐린 것 같은 그런 이상한 마무리입니다.

요약



샘플에서 사용한 사진에서도 정사각형 영역의 최대 최소값으로 인상이 크게 달라진다고 생각합니다.
잘 조절하면 주제와 배경이 제대로 그려진 그림과 같이 될지도 모르고, 포토 제닉이 요구되는 요즘, 타이틀로 나타낸대로 색다른 사진 표현으로도 활용할 수 있다고 생각합니다.
한 번 시도해 보는 것은 어떻습니까?

좋은 웹페이지 즐겨찾기