7
votes

Diffusion anisotrope Diffusion 2D images

Je veux utiliser la diffusion anisotropique sur des images 2D.

J'aimerais utiliser Python mais ne vous dérange pas d'utiliser MATLAB ou C. Leurs bibliothèques que je pourrais utiliser comme première étape? J'ai fait une recherche Google sur le sujet et trouvé Panda3D et OpenGL.
Fondamentalement, je souhaite donner à un ensemble d'images l'applique le filtrage, puis sortit la nouvelle image dans un dossier que je veux.

Toute astuce sur la manière d'utiliser l'une ou l'autre de ces ou peut-être quelque chose que vous croyez est meilleur?

Edit: signifiait la diffusion désolé!


0 commentaires

4 Réponses :


0
votes

Vous ne voulez pas dire diffusion anisotropique ? C est probablement le meilleur (plus vite que Matlab et Python). Mais il y a une boîte à outils pour l'analyse d'image dans matlab: MATLABIMAGETOOLBOX . J'ai créé un programme de diffusion isotropique en C, la seule lib i utilisée était libjpeg pour importer et exporter les images.


3 commentaires

Oh, oui désolé mon mauvais. Je voulais dire diffusion! Je suis très intéressé par la façon dont vous l'avez fait en c. Comment devrais-je aller en faire?


Non non pour les devoirs, mais pour un projet à l'UNI. Ils ont besoin de quelqu'un pour en créer un, et je veux apprendre en la créant. Je viens d'entendre parler de l'anisotrope aujourd'hui, donc j'essaie de la rechercher plutôt bien. Merci pour l'information, je ne suis pas très avancée en C mais je vais voir ce que je peux faire. Je verrai si je peux trouver n'importe quoi sur l'analyse d'images pour flotter, etc.


Les données d'image sont (si la griscale) dans un tableau de caractères non signé. Pour analyser, float_image = (flotteur) Char_Image_Data. Si vous avez besoin de plus d'aide, je peux poster du code.



15
votes

Voici My Python / Implémie implémentation de l'anisotrope 2D et 3D (Perona-Malik ) la diffusion. Ce n'est pas tout aussi rapide que C-Code, mais cela faisait le travail bien pour moi.


8 commentaires

Wow merci beaucoup! Désolé pour le retard, je viens de voir cela et ça a été très utile!


Heureux de l'entendre. Marquez ma réponse comme acceptée si cela fonctionne pour vous.


N'a pas encore beaucoup de représentant! Une fois que j'en ai assez je ferai sûrement!


En fait, Perona Malik est une diffusion isotrope (non linéaire).


@ali_m, avez-vous appliqué l'opérateur DIV deux fois comme il devrait être?


@Drazick je l'ai appelé "anisotrope" parce que la plupart des gens (y compris Perona & Malik) l'appelent cela. Cela fait longtemps que j'ai écrit ce morceau de code, mais mon souvenir est que vous n'avez que besoin de calculer la DIV une fois par dimension image, car soustrayez une copie de l'image décalée un pixel vers le bas vous donnera la même différence absolue que soustrayez Une copie a déplacé un pixel vers le haut. Il est possible que j'ai commis une erreur, cependant. Vous pouvez vérifier Fonction matlab d'origine de Peter Kovesi Si vous voulez être sûr.


Je regarde son code et encore une fois, il me semble que vous ne calculez que calculer la dérivée une fois (tandis que l'équation de diffusion de Perona Malik est la divergence du gradient, à savoir 2 dérivés.


Pour être totalement honnête, je viens de porter ce code de la version Matlab de Kovesi sans de manière rigoureuse la définition formelle de la diffusion P-M. Il est possible que sa version soit totalement fausse aussi, mais je pense que c'est peu probable, car il connaît vraiment ses affaires. Après avoir écrémé Le papier d'origine à nouveau, je pense que l'équation 7 explique ce qui se passe. Nous calculons en fait une approximation discrète de la LAPLACIAN, en utilisant 1) les différences de voisin les plus proches et 2) les gradients de conduction (également une fonction des différences de voisin les plus proches).



1
votes
import math
try:
    from cv2 import cv2
except:
    import cv2
import numpy as np


class anisodiff2D(object):

    def __init__(self,num_iter=5,delta_t=1/7,kappa=30,option=2):

        super(anisodiff2D,self).__init__()

        self.num_iter = num_iter
        self.delta_t = delta_t
        self.kappa = kappa
        self.option = option

        self.hN = np.array([[0,1,0],[0,-1,0],[0,0,0]])
        self.hS = np.array([[0,0,0],[0,-1,0],[0,1,0]])
        self.hE = np.array([[0,0,0],[0,-1,1],[0,0,0]])
        self.hW = np.array([[0,0,0],[1,-1,0],[0,0,0]])
        self.hNE = np.array([[0,0,1],[0,-1,0],[0,0,0]])
        self.hSE = np.array([[0,0,0],[0,-1,0],[0,0,1]])
        self.hSW = np.array([[0,0,0],[0,-1,0],[1,0,0]])
        self.hNW = np.array([[1,0,0],[0,-1,0],[0,0,0]])

    def fit(self,img):

        diff_im = img.copy()

        dx=1; dy=1; dd = math.sqrt(2)

        for i in range(self.num_iter):

            nablaN = cv2.filter2D(diff_im,-1,self.hN)
            nablaS = cv2.filter2D(diff_im,-1,self.hS)
            nablaW = cv2.filter2D(diff_im,-1,self.hW)
            nablaE = cv2.filter2D(diff_im,-1,self.hE)
            nablaNE = cv2.filter2D(diff_im,-1,self.hNE)
            nablaSE = cv2.filter2D(diff_im,-1,self.hSE)
            nablaSW = cv2.filter2D(diff_im,-1,self.hSW)
            nablaNW = cv2.filter2D(diff_im,-1,self.hNW)

            cN = 0; cS = 0; cW = 0; cE = 0; cNE = 0; cSE = 0; cSW = 0; cNW = 0

            if self.option == 1:
                cN = np.exp(-(nablaN/self.kappa)**2)
                cS = np.exp(-(nablaS/self.kappa)**2)
                cW = np.exp(-(nablaW/self.kappa)**2)
                cE = np.exp(-(nablaE/self.kappa)**2)
                cNE = np.exp(-(nablaNE/self.kappa)**2)
                cSE = np.exp(-(nablaSE/self.kappa)**2)
                cSW = np.exp(-(nablaSW/self.kappa)**2)
                cNW = np.exp(-(nablaNW/self.kappa)**2)
            elif self.option == 2:
                cN = 1/(1+(nablaN/self.kappa)**2)
                cS = 1/(1+(nablaS/self.kappa)**2)
                cW = 1/(1+(nablaW/self.kappa)**2)
                cE = 1/(1+(nablaE/self.kappa)**2)
                cNE = 1/(1+(nablaNE/self.kappa)**2)
                cSE = 1/(1+(nablaSE/self.kappa)**2)
                cSW = 1/(1+(nablaSW/self.kappa)**2)
                cNW = 1/(1+(nablaNW/self.kappa)**2)

            diff_im = diff_im + self.delta_t * (

                (1/dy**2)*cN*nablaN +
                (1/dy**2)*cS*nablaS +
                (1/dx**2)*cW*nablaW +
                (1/dx**2)*cE*nablaE +

                (1/dd**2)*cNE*nablaNE +
                (1/dd**2)*cSE*nablaSE +
                (1/dd**2)*cSW*nablaSW +
                (1/dd**2)*cNW*nablaNW
            )

        return diff_im

1 commentaires

Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire quant à la manière dont illave et pourquoi il résout le problème améliorerait la valeur à long terme de la réponse.



7
votes

La diffusion anisotropique est disponible dans le medpy code> Paquet depuis 2013

import numpy as np
from medpy.filter.smoothing import anisotropic_diffusion

img = np.random.uniform(size=(32,32))
img_filtered = anisotropic_diffusion(img)


1 commentaires

MEDPY semble supporter Python 3 maintenant. Page du projet GIT indique même que Python 2 n'est plus supporté.