view transformations/Rature.py @ 41:fdb0e0870fb4

Beaucoup de modifications à pipeline.py pour généraliser et un début de visualisation, et créé un wrapper (run_pipeline.py) pour appeler avec GIMP. - Modifications à pipeline.py - Wrappé la boucle du pipeline dans une classe - Isolé le problème de itérer sur les batches et les complexités dans des itérateurs - Permet d'avoir des ordres compliqués de batch (plusieurs sources), de complexités - Maintenant regenerate_parameters() est appelé pour chaque image. - Command line arguments avec getopt(). On pourra rajouter des options ainsi. - run_pipeline.py - Le but est de permettre de passer des arguments. Pas facile (pas trouvé comment de façon simple) avec la command line pour appeler GIMP en mode batch. C'est un hack ici. - Le but ultime est de permettre de lancer les jobs sur les clusters avec dbidispatch en précisant les options (diff. pour chaque job) sur la ligne de commande.
author fsavard
date Wed, 03 Feb 2010 17:08:27 -0500
parents 5848e88f7a7a
children fd02fd7e6557
line wrap: on
line source

#!/usr/bin/python
# coding: utf-8

'''
Ajout de rature sur le caractère. La rature peut etre horizontale, verticale 
(dans ces deux cas, l'amplacement de la bande est aleatoire) ou sur la diagonale
(et anti-diagonale).

La largeur de la bande ainsi que sa clarté sont definies a l'aide de complexity.
clarte: 0=blanc et 1=noir

Ce fichier prend pour acquis que les images sont donnees une a la fois
sous forme de numpy.array de 1024 (32 x 32) valeurs entre 0 et 1.

Sylvain Pannetier Lebeuf dans le cadre de IFT6266, hiver 2010

'''

import numpy
import random

class Rature():
   
    def __init__(self):
        self.largeur=2  #Largeur de la bande
        self.deplacement=0  #Deplacement par rapport au milieu
        self.orientation=0  #0=horizontal, 1=vertical, 2=oblique
        self.clarte=0.5

    def get_settings_names(self):
        return ['orientation','deplacement','clarte']

    def regenerate_parameters(self, complexity):
        #Il faut choisir parmis vertical, horizontal et diagonal.
        #La methode n'est pas exacte, mais un peu plus rapide que generer un int.
        #Complexity n'a rien a voir avec ce choix
        
        choix=numpy.random.random()
        
        if choix <0.34:
            self.orientation=0
        elif choix <0.67:
            self.orientation=1
        else:
            self.orientation=2
            
        self.largeur=int(numpy.ceil(complexity*5))
        self.clarte=complexity
        
        
        return self._get_current_parameters()

    def _get_current_parameters(self):
        return [self.orientation,self.largeur,self.clarte]

    def transform_image(self, image):
        if self.orientation == 0:
            return self._horizontal(image)
        elif self.orientation == 1:
            return self._vertical(image)
        else:
            return self._oblique(image)
        
    def _horizontal(self,image):
        self.deplacement=numpy.random.normal(0,5)
        #On s'assure de rester dans l'image
        if self.deplacement < -16:  #Si on recule trop
            self.deplacement = -16
        if self.deplacement+self.largeur > 16: #Si on avance trop
            self.deplacement=16-self.largeur
        for i in xrange(0,self.largeur):
            for j in xrange(0,31):
                image[i+15+self.deplacement,j]=min(1,image[i+15+self.deplacement,j]+self.clarte)
        return image
    
    def _vertical(self,image):
        self.deplacement=numpy.random.normal(0,5)
        #On s'assure de rester dans l'image
        if self.deplacement < -16:  #Si on recule trop
            self.deplacement = -16
        if self.deplacement+self.largeur > 16: #Si on avance trop
            self.deplacement=16-self.largeur
        for i in xrange(0,self.largeur):
            for j in xrange(0,31):
                image[j,i+15+self.deplacement]=min(1,image[j,i+15+self.deplacement]+self.clarte)
        return image
    
    def _oblique(self,image):
        decision=numpy.random.random()
        D=numpy.zeros((32,32)) #La matrice qui sera additionnee
        for i in xrange(int(-numpy.floor(self.largeur/2)),int(numpy.ceil((self.largeur+1)/2))):
            D+=numpy.eye(32,32,i)
        if decision<0.5: #On met tout sur l'anti-diagonale
            D = D[:,::-1]
        D*=self.clarte
        image+=D
        for i in xrange(0,32):
            for j in xrange(0,32):
                image[i,j]=min(1,image[i,j])  #Afin de toujours avoir des valeurs entre 0 et 1    
        return image


#---TESTS---

def _load_image():
    f = open('/home/sylvain/Dropbox/Msc/IFT6266/donnees/lower_test_data.ft')  #Le jeu de donnees est en local. 
    d = ft.read(f)
    w=numpy.asarray(d[1])
    return (w/255.0).astype('float')

def _test(complexite):
    img=_load_image()
    transfo = Rature()
    pylab.imshow(img.reshape((32,32)))
    pylab.show()
    print transfo.get_settings_names()
    print transfo.regenerate_parameters(complexite)
    img=img.reshape((32,32))
    
    img_trans=transfo.transform_image(img)
    
    pylab.imshow(img_trans.reshape((32,32)))
    pylab.show()
    

if __name__ == '__main__':
    from pylearn.io import filetensor as ft
    import pylab
    _test(0.8)