[PYTHON] Proposition du filtre Kuwahara comme expression photographique

introduction

** Qu'est-ce que le filtre Kuwahara ** Veuillez consulter ce qui précède pour une explication du filtre Kuwahara.

Cette fois

Cette fois, j'ai fait une suggestion rapide à la fin de ce qui précède.

"Il peut être intéressant d'avoir une carte de profondeur et d'ajuster la taille de la zone carrée en conséquence ..."

J'aimerais vraiment essayer.

Cette idée est que si le sujet principal n'est pas clair (flou n'importe où), il ressemble plus à un arrière-plan qu'à une peinture, par rapport à l'image précédente qui a un côté constant de la zone carrée et est filtrée. Il a été obtenu sur la base de.

la mise en oeuvre

En réponse à l'article précédent, il y avait une opinion que la signification du code n'était pas compréhensible (difficile), donc je l'ai écrit dans le code "Sonomanma", qui est hors de la vitesse de calcul. Cependant, laisser Python laisser trop de boucles tel quel prendrait beaucoup de temps d'exécution, j'ai donc aidé avec le compilateur JIT. Pour ceux qui n'ont pas Numba (une bibliothèque qui inclut JIT), [Comment accélérer considérablement le code Python en utilisant la bibliothèque de compilateur JIT Numba](https://myenigma.hatenablog.com/entry/2017/03/ Veuillez vous référer au 02/155433).

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 = max(r_min, int(depth[i, j]*r))
            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): #Chemin de l'image d'entrée, valeur maximale d'un côté de la zone carrée, valeur minimale d'un côté de la zone carrée, rapport de réduction de la taille de l'image, chemin de la carte de profondeur
    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])) #Pour lorsque l'orientation de la carte de profondeur ne correspond pas à l'image d'origine
    fpic = kuwahara_with_depth(pic, r, r_min, depth).astype(pic.dtype)
    plt.imshow(fpic)
    # plt.imshow(np.rot90(fpic,3)) #Pour lorsque l'image de sortie est tournée sur le côté
    plt.show()


picpath = "input_pic.jpg " #Chemin de l'image d'entrée
depthpath = "depthmap.jpg " #Chemin de l'image de la carte de profondeur

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

résultat

Encore une fois, j'utiliserai ** French Nekko ** comme échantillon de la photo française. Dans l'explication ci-dessus, cela a été exprimé sous forme de carte de profondeur, mais bien sûr, il n'y a pas de telles données, donc je vais créer une image qui lui ressemble d'une certaine manière. Cette fois, je l'ai fait correctement avec une exposition de photos. À propos, plus la zone est blanche, plus un côté de la zone carrée est grand. (Il semble que certains fichiers photo de smartphone qui peuvent utiliser le flou d'arrière-plan contiennent des informations de carte de profondeur. [Création d'images stéréo / d'images multi-points de vue à l'aide de la carte Google Camera Deph](http: //stereo.jpn) .org / kitkat / index.html)))

Voici celui qui a été filtré cette fois à l'aide de ceux-ci. Veuillez cliquer pour agrandir et voir. C'est une finition mystérieuse, comme une fusion naturelle d'une photo et d'une image, comme un flou avec de la peinture au lieu de brouiller l'objectif.

Résumé

Même sur les photos utilisées dans l'échantillon, je pense que l'impression va beaucoup changer en fonction des valeurs maximales et minimales de la surface carrée. Si elle est bien ajustée, elle peut ressembler à une peinture dans laquelle le sujet et l'arrière-plan sont clairement dessinés, et en ces jours où la photogénicité est requise, je pense qu'elle peut être utilisée comme une expression photographique inhabituelle comme indiqué dans le titre. Pourquoi ne pas essayer?

Recommended Posts

Proposition du filtre Kuwahara comme expression photographique
Mise en place d'un filtre à particules simple
Langage du bouclier var0.1
Une vérification des performances du kit AWS SDK par langue
Proposition du filtre Kuwahara comme expression photographique
Tâches au démarrage d'un nouveau projet python
Caractéristiques du langage Go
Obtenez le nom de la variable sous forme de chaîne de caractères.
(Python) Traite les valeurs entières comme un ensemble d'indicateurs
Calculer le produit des matrices avec une expression de caractère?