예제 #1
0
def improve_ia(root):
    """Hyperparameter tuning"""
    mt = MyTools()

    imshow = 1

    # Création du dossier weights si besoin
    mt.create_directory(os.path.join(root, 'weights'))

    size = 40  # fixe
    for gray in GRAY:
        print("gray", gray)
        for blur in BLUR:
            print("blur", blur)
            # resize blur
            rb = ResizeBlur(root, size, blur, imshow)
            rb.batch()
            del rb

            # compression
            sc = ShotsCompression(root, TRAIN, TEST, size, gray, imshow)
            sc.create_semaphore_npz()
            del sc

            for learningrate in LEARNINGRATE:
                print("learningrate", learningrate)
                failed = 0
                for k in range(NOMBRE_DE_PASSE):
                    sia = SemaphoreIA(root, TRAIN, learningrate, failed,
                                      imshow)
                    weight_list = sia.training()
                    resp = sia.testing()
                    print("Result:", resp)
                    save_test(root, resp, weight_list, gray, blur,
                              learningrate)
예제 #2
0
def create_directories():
    """
    Création de n dossiers
    un fichier = ./semaphore/shot/shot_0/shot_a_0.png
    """

    # Dossier d'enregistrement des images
    gl.shot_directory = os.path.join(gl.root, 'training_shot')
    print("Dossier des shots:", gl.shot_directory)

    # Si le dossier n'existe pas, je le crée
    mt = MyTools()
    mt.create_directory(gl.shot_directory)

    # Nombre de dossiers nécessaires
    n = int(gl.nombre_shot_total / gl.nombre_de_fichiers_par_dossier) + 1

    for i in range(n):
        directory = os.path.join(gl.shot_directory, 'shot_' + str(i).zfill(3))
        mt.create_directory(directory)
예제 #3
0
class CreateShot:
    def __init__(self, size, video, number=1000):
        """
        letters = {'a': image de a,
                   ' ': image de ' ',
                   etc ...}
        """
        self.size = size
        self.number = number

        self.tools = MyTools()
        self.create_directories()
        self.letters = self.get_letters_images()
        self.numero_lettre = 0

        self.capture = cv2.VideoCapture(video)
        self.width = int(self.capture.get(cv2.CAP_PROP_FRAME_WIDTH))
        self.height = int(self.capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
        print("Taille Video:", self.width, self.height)

        self.get_shots()

    def create_directories(self):
        """Un dossier root=shot, un sous dossier par lettre"""

        self.tools.create_directory("./shot")
        for l in LETTRES:
            if l == " ":
                l = "space"
            self.tools.create_directory("./shot/shot_" + l)

    def get_letters_files(self):
        letters_files = self.tools.get_all_files_list("lettre_epaisse_alpha",
                                                      ".png")
        print("Nombre de letters =", len(letters_files))
        return letters_files

    def get_letters_images(self):
        """Récupère toutes les images de lettres"""

        letters = {}
        for l_file in self.get_letters_files():
            # lettre/shot_10_j.png
            l = l_file[:-4][-1]
            img = cv2.imread(l_file, -1)
            img = delete_gray(img)
            letters[l] = img
        return letters

    def frame_resize(self, frame):
        """Pour 1024: resize puis coupe des 2 cotés de 398
        pour 416: 1280x720 devient 739x416
        """

        # Largeur
        a = int(self.width * self.size / self.height)
        # Hauteur
        b = self.size
        # Resize
        frame = cv2.resize(frame, (a, b), interpolation=cv2.INTER_AREA)

        # Coupe
        x = int((a - b) / 2)
        y = 0
        w, h = self.size, self.size
        frame = frame[y:y + h, x:x + w]

        return frame

    def aspect_change(self, lettre):
        """Couleur, flou, rotation
        lettre est l'image de la lettre
        """

        bg_color = lettre[0][0]
        R = random.randint(0, 100)
        G = random.randint(0, 50)
        B = random.randint(100, 255)
        lettre[np.all(lettre == [0, 0, 0, 255], axis=2)] = [R, G, B, 255]
        mask = np.all(lettre == bg_color, axis=2)
        lettre[mask] = [0, 0, 0, 0]

        # Rotation
        some = random.randint(-3, 3)
        lettre = rotateImage(lettre, some)

        # Flou de 0 à 4
        flou = random.randint(0, 4)
        if flou != 0:
            lettre = cv2.blur(lettre, (flou, flou))

        return lettre

    def lettre_image_change(self, lettre):
        """Adapte une lettre, calcule taille, position, flou, couleur
        lettre est l'image de la lettre
        """

        # Modification de l'aspect
        lettre = self.aspect_change(lettre)

        # Variation sur la taille du sémaphore
        semaphore_mini = int(self.size / 7)

        w, h = lettre.shape[1], lettre.shape[0]
        # Set de la hauteur, puis largeur
        y_size = random.randint(semaphore_mini, int(self.size * 0.8))
        x_size = int(w * y_size / h)

        # Maxi de taille de lettre < self.size
        y_size = min(y_size, self.size)
        x_size = min(x_size, self.size)

        lettre = cv2.resize(lettre, (x_size, y_size),
                            interpolation=cv2.INTER_CUBIC)

        # Position posible
        x = random.randint(0, self.size - x_size)
        y = random.randint(0, self.size - y_size)

        return lettre, x_size, y_size, x, y

    def overlay(self, frame):
        """Trouve une lettre, supperpose à la frame"""

        # Lecture des lettres de l'alphabet en boucle
        l = LETTRES[self.numero_lettre]
        self.numero_lettre += 1
        if self.numero_lettre == 27:
            self.numero_lettre = 0

        # lettre est l'image de lettre
        lettre = self.letters[l]

        # Adaptation
        lettre, x_size, y_size, x, y = self.lettre_image_change(lettre)

        # Overlay
        img = over_transparent(frame, lettre, x, y)

        return img, l, x_size, y_size, x, y

    def save(self, img, lettre, x_size, y_size, x, y, n):
        """Enregistrement dans le dossier ./shot/shot_a/ de
        shot_0_a.jpg et shot_0_a.txt
        class position(x y) taille(x y)
        x, y position du coin haut gauche
        s = taille de la lettre
        """

        # Get indice avant modif liste
        indice = LETTRES.index(lettre)

        # pour avoir dossier clair
        if lettre == " ":
            lettre = "space"

        # Avec sous dossiers
        fichier = "./shot/shot_" + lettre + "/shot_" + str(n) + "_" + lettre

        # Enregistrement de l'image
        cv2.imwrite(fichier + ".jpg", img)

        # Enregistrement des datas
        # Taille relative de l'image lettre
        tx = x_size / self.size
        ty = y_size / self.size

        # Origine = top left
        xc = (x + (x_size / 2)) / self.size
        yc = (y + (y_size / 2)) / self.size
        # class-position du centre-taille
        data = (str(indice) + " " + str(xc) + " " + str(yc) + " " + str(tx) +
                " " + str(ty))

        self.tools.write_data_in_file(data, fichier + ".txt", "w")

    def get_shots(self):
        n, m = 0, 0
        self.loop = 1
        while self.loop:
            ret, frame = self.capture.read()
            if ret:
                # pour enregistrer 1 frame sur 10 et varier les fonds
                if n % 10 == 0:
                    frame = self.frame_resize(frame)

                    # Overlay d'une lettre
                    img, l, x_size, y_size, x, y = self.overlay(frame)

                    print("Shot numéro", m, "Lettre", l)

                    # Enregistrement de l'image et du fichier txt
                    self.save(img, l, x_size, y_size, x, y, m)
                    m += 1

                cv2.imshow("image", img)

                # Jusqu'à number
                n += 1
                if m == self.number:
                    self.loop = 0

                # Echap et attente
                k = cv2.waitKey(10)
                if k == 27:
                    self.loop = 0
            else:
                # Reset si la video est terminée
                self.capture = cv2.VideoCapture(video)

        print("Nombre d'images crées:", m)
        cv2.destroyAllWindows()
예제 #4
0
class BlurAndConvert:

    def __init__(self):
        self.mt = MyTools()

        self.blur_mini = CONF["letters_shot_jpg"]["blur_mini"]
        self.blur_maxi = CONF["letters_shot_jpg"]["blur_maxi"]
        self.size = CONF["letters_shot_jpg"]["shot_size"]
        
        # Dossiers
        self.shot = shot_dir
        print("Dossier shot:", self.shot)
        self.create_shot_jpg()
        self.create_sub_directories()

        # Images png
        self.all_png_files = self.mt.get_all_files_list(self.shot, '.png')
        print("Nombre de fichiers à convertir:", len(self.all_png_files))
        if len(self.all_png_files) == 0:
            print("\n\nPas d'images à convertir")
            print("Créer les images avant !")
            os._exit(0)

        # Exécution du script flou puis save
        self.save_to_jpg()

    def create_shot_jpg(self):
        self.shot_jpg = shot_jpg
        print("Dossier shot_jpg:", self.shot_jpg)
        # Si le dossier n'existe pas, je le crée
        self.mt.create_directory(self.shot_jpg)

    def create_sub_directories(self):
        """Création de 100 dossiers."""

        # Répartition dans 100 sous dossiers
        for l in range(100):
            directory = os.path.join(self.shot_jpg, str(l))
            self.mt.create_directory(directory)

    def blur(self, img):
        # Flou

        k = random.randint(self.blur_mini, self.blur_maxi)
        if k != 0:
            img = cv2.blur(img, (k, k))
        return img

    def save_to_jpg(self):
        n = 0

        for png in self.all_png_files:
            if n % 100 == 0 and n != 0:
                a = len(self.all_png_files)
                print("Nombre de fichiers convertis:", n, "sur", a)
            n += 1

            # Lecture de png
            img = cv2.imread(png)

            # Flou
            img = self.blur(img)

            # Retaillage avec size de letters.ini
            img = cv2.resize(img, (self.size, self.size), interpolation=cv2.INTER_AREA)

            # On travaille avec Path
            png_path = Path(png)
            jpg_path = self.get_jpg_name(png_path)  # PosixPath
            
            # Ecriture de l'image jpg, cv2 prend seulement path en str
            cv2.imwrite(str(jpg_path), img,
                                       [int(cv2.IMWRITE_JPEG_QUALITY),
                                       100])
            
            # Copie du fichier txt de png dans jpg
            txt, dst = self.get_txt_dst(png_path, jpg_path)
            copyfile(txt, dst)

            # On prend son temps
            sleep(0.01)
            
        print("Nombre de fichiers convertis:", n)

    def get_jpg_name(self, png_path):
        """ png = str
        png = str(self.shot)     + /25/shot_4126.png = str
        jpg = str(self.shot_jpg) + /25/shot_4126.jpg = str
        """

        # Soustraction du chemin de shot_dir
        a = str(png_path).replace(str(shot_dir), "")
        # Ajout du chemin de jpg_dir
        b = Path(str(shot_jpg) + a)

        # Changement de l'extension
        jpg_path = b.with_suffix(".jpg")

        return jpg_path
            
    def get_txt_dst(self, png_path, jpg_path):
        
        txt_path = png_path.with_suffix(".txt")
        dst_path = jpg_path.with_suffix(".txt")

        return txt_path, dst_path
예제 #5
0
class AnalyseMidi:
    """Analyse le fichier midi,
    trouve le nombre et le nom des instruments.
    Retourne la liste des notes sur une time lapse de chaque instrument.
    save_midi_json enregistre le midi en json

    partitions = liste des partitions
    instruments = liste des instruments soit objet avec .program et .name

    L'enregistrement des json avec chemins absolus ne marche que pour letters

    Sous répertoires et sous sous répertoires possible dans /music
    """

    def __init__(self, midi_file, FPS, volume=""):
        """Un seul fichier midi
        FPS de 10 à 1000, 50 ou 100 est bien
        Plus le FPS est élevé, plus le temps de calcul est long !
        """

        print("\n\nAnalyse de", midi_file.split('/')[-1], "\n")

        self.midi_file = midi_file
        self.FPS = FPS
        self.volume = volume
        
        self.end_time = 0
        self.instruments = None
        self.instruments = []
        self.partitions = []
        self.mytools = MyTools()

        # Pour gérer les threads dans blender
        self.end = 0
        
    def get_instruments(self):
        """instruments =
        [Instrument(program=71, is_drum=False, name="Grand Piano"), ...]
        """

        # Récupération des datas avec pretty_midi
        midi_pretty_format = my_pretty_midi.PrettyMIDI(self.midi_file)

        # Supprime les notes avec fin avant le début !
        midi_pretty_format.remove_invalid_notes()

        # Time de fin, instruments du fichier
        self.end_time = midi_pretty_format.get_end_time()
        self.instruments_without_drums = midi_pretty_format.instruments

        # Correction des intruments pour avoir le program des drums
        self.get_instruments_with_drums()

        return self.instruments

    def get_instruments_with_drums(self):
        """"De:
            [Instrument(program=25, is_drum=False, name="Bass"),
             Instrument(program=0, is_drum=True, name="Drums"),
             Instrument(program=0, is_drum=True, name="Drums2")]

            pour une liste de tuple:
            [((0, 25), False, "Bass"),
             ((0, 116), True, "Drums"),
             ((8, 115), True, "Drums2")]

        Pour le dict du json
        "instruments": [[(0, 25), false], [(0, 116), true], [(8, 116), true]]}
        """

        for instrument in self.instruments_without_drums:
            program = instrument.program
            is_drum = instrument.is_drum
            name = instrument.name

            if is_drum:
                bank, bank_nbr = self.get_drum_program()
            else:
                bank = 0
                bank_nbr = int(program)
            self.instruments.append(((bank, bank_nbr), is_drum, name))

    def get_drum_program(self):
        """ Cas possible:
                0 114 Steel Drums
                0 115 Woodblock
                0 116 Taiko Drum
                0 117 Melodic Tom
                0 118 Synth Drum
                0 119 Reverse Cymbal
                8 116 Concert Bass Drum
                8 117 Melo Tom 2
                8 118 808 Tom
        """

        drums = [(0, 112),
                 (0, 113),
                 (0, 114),
                 (0, 115),
                 (0, 116),
                 (0, 117),
                 (0, 118),
                 (0, 119),
                 (8, 116),
                 (8, 117),
                 (8, 118)]
        c = choice(drums)
        return c[0], c[1]

    def get_partitions_and_instruments(self):
        """Fait les étapes pour tous les instruments,
        retourne les instruments et leurs partitions.
        """

        # Si fichier midi anormal
        try:
            self.get_instruments()
        except:
            print("Instruments non récupérable dans le fichier midi\n")
            self.instruments_without_drums = []

        # Si nombre d'instrument > 10 pour IA
        if len(self.instruments) > 10:
            return None, None
            
        for instrument in self.instruments_without_drums:
            if instrument.is_drum:
                drum = "Drum"
            else:
                drum = ""
            print("    Analyse de l'instrument: {:>2} {:>6}   Name: {:>24}".\
            format(instrument.program, drum, instrument.name))

            # Array de 128 x nombre de frames
            instrument_roll = self.get_instrument_roll(instrument)

            # Conversion dans une liste de listes python
            partition = self.get_partition(instrument_roll, instrument)
            self.partitions.append(partition)
        print()
        return self.partitions, self.instruments

    def get_partition(self, instrument_roll, instrument):
        """entrée:
        une ligne du array = (0.0 0.0 0.0 ... 89 ... 91 ... 0.0)
                                             89 est à la position 54
                                                    91 est à la position 68
        sortie:
        une ligne de la liste: 2 notes du même instrument 54 et 68
            [(54, 89), (68, 91)] = [(note=54, volume=89), (note=68, volume=91)]
        """

        partition = []
        
        # Parcours de toutes les lignes
        for n in range(instrument_roll.shape[1]):
            # Analyse des lignes pour ne garder que les non nuls
            non_zero = np.flatnonzero(instrument_roll[:,n])
            notes = []
            if non_zero.size > 0:
                note = int(non_zero[0])
                volume = int(instrument_roll[:,n][note])
                if note:
                    notes.append((note, volume))
            partition.append(notes)

        # velocity maxi entre 0 et 127
        partition = normalize_velocity(partition)
        if self.volume == "flat":
            partition = flatten_partition(partition)
        
        return partition
        
    def get_instrument_roll(self, partition):
        """Retourne un np.array de (128, FPS*durée du morceau en secondes)"""

        # La méthode get_piano_roll marche pour tous les instruments
        instrument_roll = partition.get_piano_roll(self.FPS,
                                                   np.arange(0,
                                                             self.end_time,
                                                             1/self.FPS))

        return instrument_roll

    def save_midi_json(self):
        """Commence par analyser le midi, puis enregistre.
        
        partitions = liste des partitions = [partition_1, partition_2 ...]
        instruments = [Instrument(program=71, is_drum=False, name="mélodie"),
                        ...]

        json_data = {"partitions":  [partition_1, partition_2 ......],
                     "instruments": [instrument_1.program,
                                     instrument_2.program, ...]
                      instrument is not JSON serializable = objet pretty_midi

        midi dans /media/data/3D/projets/darknet-letters/letters/midi/music
                     sous dossiers possible
        json dans /media/data/3D/projets/darknet-letters/letters/midi/json_fps
        et sous dossiers
        """

        # Analyse du midi
        self.get_partitions_and_instruments()

        if len(self.instruments) < 11:
            # Création du json
            json_data = {}
            json_data["partitions"] = self.partitions
            json_data["instruments"] = self.instruments
            
            # Save du json
            json_name = self.get_json_name()
            with open(json_name, 'w') as f_out:
                json.dump(json_data, f_out)
            f_out.close()
            print('Enregistrement de:', json_name)

        # Pour Blender
        self.end = 1

        return self.instruments
        
    def get_json_name(self):
        """Le fichier midi_file est le chemin relatif du fichier dans :
        ./midi/music/
             ou 
        ./midi/music/non_git/

        Le json sera dans le dossier 
        ./midi/json_60/
        ou
        ./midi/json_60/non_git/
        """

        # Remplacement de l'extension .midi en .json
        filename = Path(self.midi_file).with_suffix(".json")
        filename = str(filename)
        
        # Remplacement de music par json
        json_name = filename.replace("music/",
                                     "json_" + str(self.FPS) + "/")

        print("Nom du fichier json", json_name)
        
        # Crée les dossiers et sous dossiers
        self.create_directories(json_name)
        
        return json_name

    def create_directories(self, json_name):
        """
        json_name converti en absolu pour valable ici ou dans blender

        json_name = /med/da/3D/pr/dark/let/midi/json_fps_17/toto.json
                                        5
        json_fps =  /med/da/3D/pr/dark/let/midi/json_fps_17/oui/toto.json
                                                    7
        """

        json_name_abs = Path(json_name).absolute()
        
        # json_17 doit toujours exister, si existe on passe
        index_midi = json_name_abs.parts.index("midi")

        # Bidouille pour agréger les parts
        a = Path(json_name_abs.parts[0])
        b = json_name_abs.parts[1:index_midi + 2]
        json_fps = a.joinpath(*b)
        
        # json_fps = Chemin absolu de json_fps
        self.mytools.create_directory(json_fps)

        # Sous répertoires
        if len(json_name_abs.parts) - index_midi == 4:
            sd_fin = json_name_abs.parts[1:index_midi + 3]
            sd = a.joinpath(*sd_fin)
            print("Sous dossier", sd)
            self.mytools.create_directory(sd)
            
        # Sous sous répertoires
        if len(json_name_abs.parts) - index_midi == 5:
            # Création du sous répertoire
            sd_fin = json_name_abs.parts[1:index_midi + 3]
            sd = a.joinpath(*sd_fin)
            print("Sous dossier", sd)
            self.mytools.create_directory(sd)
            
            # Création des sous sous répertoires
            ssd_fin = json_name_abs.parts[1:index_midi + 4]
            ssd = a.joinpath(*ssd_fin)
            print("Sous sous dossier", ssd)
            self.mytools.create_directory(ssd)
예제 #6
0
class ResizeTrainingShot:
    def __init__(self, root, size):
        self.root = root  # soit ..../semaphore
        self.size = int(size)

        # Mes outils personnels
        self.tools = MyTools()

        # Renommage de training_shot en training_shot_copy
        self.rename_training_shot()

        # Re-création des dossiers
        self.create_training_shot_dir()
        self.create_sub_folders()

        # Liste des images
        self.shot_list = self.get_shot_list()

    def rename_training_shot(self):
        ori = os.path.join(self.root, "training_shot")
        dest = os.path.join(self.root, "training_shot_copy")
        os.rename(ori, dest)

    def create_training_shot_dir(self):
        directory = os.path.join(self.root, "training_shot")
        print("Dossier training_shot:", directory)
        self.tools.create_directory(directory)

    def create_sub_folders(self):
        """Création de n dossiers shot_000"""

        # Nombre de dossiers nécessaires
        d = os.path.join(self.root, "training_shot_copy")
        n = len(self.tools.get_all_sub_directories(d)) - 1
        print("Nombre de sous répertoires", n)
        for i in range(n):
            directory = os.path.join(self.root, 'training_shot',
                                     'shot_' + str(i).zfill(3))
            self.tools.create_directory(directory)
        print("Sous répertoires créés")

    def get_shot_list(self):
        """Liste des images"""

        # Liste
        shot = os.path.join(self.root, "training_shot_copy")
        shot_list = self.tools.get_all_files_list(shot, ".png")

        print("Dossier des images NB:", shot)
        print("Nombre d'images:", len(shot_list))

        return shot_list

    def change_resolution(self, img, x, y):
        """Une image peut-être ratée"""

        try:
            res = cv2.resize(img, (x, y), interpolation=cv2.INTER_AREA)
        except:
            res = np.zeros([self.size, self.size, 1], dtype=np.uint8)
        return res

    def get_new_name(self, shot):

        return shot.replace("/training_shot_copy/", "/training_shot/")

    def create_training_shot_resized_dir(self):

        directory = os.path.join(self.root, "training_shot_resized")
        print("Dossier training_shot_resized:", directory)
        self.tools.create_directory(directory)

    def batch(self):
        """Lecture, resize, save"""

        i = 0

        # Pour chaque image
        for shot in self.shot_list:
            # Lecture
            img = cv2.imread(shot, 0)

            # Resize
            img_out = self.change_resolution(img, self.size, self.size)
            i += 1

            # Save
            new_shot = self.get_new_name(shot)
            print(new_shot)
            cv2.imwrite(new_shot, img_out)
예제 #7
0
class ResizeBlur:
    def __init__(self, root, size, blur, imshow=1):
        """ root = dossier semaphore
            size = taille des images pour l'ia
            blur = 0 à 10 pour flouter les images pour l'ia
            imshow = 0 ou 1 pour affichage d'image ou non pendant l'exécution
        """

        self.root = root  # soit ..../semaphore
        self.size = int(size)
        self.size = max(20, self.size)
        self.size = min(800, self.size)
        self.blur = blur
        self.imshow = imshow

        # Mes outils personnels
        self.tools = MyTools()

        # Le terrain de jeu
        self.create_training_shot_resized_dir()

        # Liste
        self.shot_list = self.get_shot_list()

        self.create_sub_folders()

    def create_training_shot_resized_dir(self):

        directory = os.path.join(self.root, "training_shot_resized")
        print("Dossier training_shot_resized:", directory)
        self.tools.create_directory(directory)

    def create_sub_folders(self):
        """Création de n dossiers shot_000"""

        # Nombre de dossiers nécessaires
        d = os.path.join(self.root, "training_shot")
        n = len(self.tools.get_all_sub_directories(d)) - 1
        print("Nombre de sous répertoires", n)
        for i in range(n):
            directory = os.path.join(self.root, 'training_shot_resized',
                                     'shot_' + str(i).zfill(3))
            self.tools.create_directory(directory)

    def get_new_name(self, shot):
        """ de
        /media/data/3D/projets/semaphore/training_shot/shot_000/shot_0_a.png
        à
        /media/data/3D/projets/semaphore/training_shot_resized/shot_000/shot_0_a.png
        j'ai
        /media/data/3D/projets/semaphore/training_shot_resized/shot_000/shot_3921_h.png
        """

        t = shot.partition("training_shot")
        # t = ('/media/data/3D/projets/semaphore/', 'training_shot',
        #                                       '/shot_000/shot_1054_s.png')
        name = os.path.join(self.root, "training_shot_resized", t[2][1:])

        return name

    def change_resolution(self, img, x, y):
        """Une image peut-être ratée"""

        try:
            res = cv2.resize(img, (x, y), interpolation=cv2.INTER_AREA)
        except:
            res = np.zeros([self.size, self.size, 1], dtype=np.uint8)
        return res

    def apply_blur(self, img, k):
        """TODO: Utiliser GaussianBlur
        img = cv2.GaussianBlur(img, (5, 5), 0)
        """

        if self.blur:
            img = cv2.blur(img, (k, k))
        return img

    def random_noise(self, img):
        """Entre 0 et 20 pixels au hasard"""

        nb = random.randint(0, 10)

        for i in range(nb):
            x = random.randint(0, 39)
            y = random.randint(0, 39)
            img[x][y] = 1

        return img

    def some_dirty(self, img):
        """0 à 3 paquets de 4 pixels
        0 1 0
        1 1 1
        0 1 0
        """

        nb = random.randint(0, 2)
        for i in range(nb):
            x = random.randint(0, 34)
            y = random.randint(0, 34)

            # 1ère ligne
            a = x + 1
            b = y + 0
            img[a][b] = 1

            # 2ème ligne
            for u in range(3):
                a = x + u
                b = y + 1
                img[a][b] = 1

            # 3ème ligne
            a = x + 1
            b = y + 2
            img[a][b] = 1

        return img

    def batch(self):
        """Liste des images, lecture, conversion, save"""

        i = 0
        if self.imshow:
            cv2.namedWindow('Image In')
            cv2.namedWindow('Image Out')

        # Pour chaque image
        for shot in self.shot_list:
            # Lecture
            img = cv2.imread(shot, 0)

            # ResizeBlur
            img_out = self.change_resolution(img, self.size, self.size)

            # Flou
            img_out = self.apply_blur(img_out, self.blur)

            # Noise
            # L'ajout de bruit est appris par le réseau et va dégrader la
            # reconnaissance, mais Jo dit que non, ça dépend de ???
            # #img_out = self.random_noise(img_out)
            # #img_out = self.some_dirty(img_out)

            # ## Affichage
            if self.imshow:
                if i % 500 == 0:
                    #print(i)
                    imgB = self.change_resolution(img_out, 600, 600)
                    cv2.imshow('Image In', img)
                    cv2.imshow('Image Out', imgB)
                    cv2.waitKey(1)
            i += 1

            # Save
            new_shot = self.get_new_name(shot)
            cv2.imwrite(new_shot, img_out)

        cv2.destroyAllWindows()

    def get_shot_list(self):
        """Liste des images"""

        # Liste
        shot = os.path.join(self.root, "training_shot")
        shot_list = self.tools.get_all_files_list(shot, ".png")

        print("Dossier des images NB:", shot)
        print("Nombre d'images:", len(shot_list))

        return shot_list
예제 #8
0
class YOLO:
    def __init__(self, images_directory, essai, save, test=0, weights=""):
        """
        essai = numéro del'eaasi dans ini
        save = sauvegarde des notes en json
        test = bidouilles pour passer une série de weights
        """

        # Mes outils
        self.mt = MyTools()

        self.lp = LettersPath()
        self.CONF = self.lp.conf
        self.essai = essai
        self.save = save
        self.test = test

        self.weights = weights
        if self.weights:
            print("Fichier de poids utilisé:", self.weights)
        self.get_weights_file_indice()
        if self.weights:
            self.create_test_subdir()

        # Paramètres de la conf
        # Avec ou sans GPU
        self.gpu = self.CONF['play_letters']['gpu']
        # Résolution de l'écran ou du VP: x, y
        self.screen = self.CONF['play_letters']['screen']

        # Boucle opencv
        self.loop = 1
        self.fps = 0

        # Récup des images
        self.images_directory = images_directory
        self.shot_list = self.get_sorted_shot_list()
        self.all_shot = self.get_all_shot()

        # nom du morceau
        self.filename = self.images_directory.split("/")[-1]

        # Initialisation de la détection
        self.set_darknet()

        # Paramètres de détections
        self.thresh = int(self.CONF['play_letters']['thresh'])
        self.hier_thresh = int(self.CONF['play_letters']['hier_thresh'])
        self.nms = int(self.CONF['play_letters']['nms'])

        # Windows
        self.create_windows()

        # Trackbars
        self.create_trackbar()
        self.set_init_tackbar_position()

        # Midi
        self.fonts = self.CONF['music_and_letters']['fonts']
        self.instruments = []
        self.get_instruments()
        self.notes_en_cours = []
        self.players = {}
        self.set_players()
        self.all_notes = []

    def create_windows(self):
        cv2.namedWindow('Reglage')
        cv2.moveWindow('Reglage', 0, 25)
        self.fullscreen = self.CONF['play_letters']['fullscreen']
        if self.fullscreen:
            cv2.namedWindow('Letters', cv2.WND_PROP_FULLSCREEN)
            cv2.setWindowProperty('Letters', cv2.WND_PROP_FULLSCREEN,
                                  cv2.WINDOW_FULLSCREEN)
        else:
            cv2.namedWindow('Letters')
            cv2.moveWindow('Letters', 0, 25)
        self.titre = 0
        b = int(416 * self.screen[0] / self.screen[1])
        self.black_image = np.zeros((416, b, 3), np.uint8)

    def get_weights_file_indice(self):
        """Uniquement pour test
        weightpath =
        ../darknet/data_22/backup/yolov3-tiny_3l_22_best.weights
        début = ../darknet/data_22/backup/yolov3-tiny_3l_22_
        fin = .weights
        """

        a = len(
            "/media/data/projets/darknet-letters/letters/darknet/data_22/backup/yolov3-tiny_3l_22_"
        )
        b = len(".weights")
        indice = str(self.weights[a:-b])

        return indice

    def create_test_subdir(self):
        doss = "/media/serge/BACKUP/play_letters_shot/pl_shot_14_jpg/test/"
        for i in range(43):
            directory = doss + str((i + 1) * 1000)
            self.mt.create_directory(directory)

    def set_darknet(self):
        """Si weight_influence_test,
        teste tous les
        yolov3-tiny_3l_22_xxxxxxx.weights
        du dossier backup

        free_network = lib.api_free_network
        free_network.argtypes = [c_void_p]

        adapté à ce script:
        free_network = darknet.lib.api_free_network
        free_network.argtypes = [c_void_p]
        """

        configPath = self.CONF['play_letters']['configpath']

        if not self.test:
            weightPath = self.CONF['play_letters']['weightpath']
        else:
            weightPath = self.weights

        metaPath = self.CONF['play_letters']['metapath']

        self.netMain = darknet.load_net_custom(configPath.encode("ascii"),
                                               weightPath.encode("ascii"), 0,
                                               1)
        self.metaMain = darknet.load_meta(metaPath.encode("ascii"))

        with open(metaPath) as metaFH:
            metaContents = metaFH.read()
            match = re.search("names *= *(.*)$", metaContents,
                              re.IGNORECASE | re.MULTILINE)
            if match:
                result = match.group(1)
            else:
                result = None
            try:
                if os.path.exists(result):
                    with open(result) as namesFH:
                        namesList = namesFH.read().strip().split("\n")
                        self.altNames = [x.strip() for x in namesList]
            except TypeError:
                print("Erreur self.altNames")

        if self.gpu:
            self.free_network = darknet.lib.api_free_network

        # Create an image we reuse for each detect
        self.darknet_image = darknet.make_image(\
                                        darknet.network_width(self.netMain),
                                        darknet.network_height(self.netMain),
                                        3)

    def get_instruments(self):
        """Récupère les infos de instruments.txt dans self.instruments."""

        file_name = self.images_directory + "/instruments.txt"
        data = self.mt.read_file(file_name)

        if data:
            lines = data.splitlines()
            for line in lines:
                line_list = line.split(" ")
                self.instruments.append(line_list)
        else:
            print("Pas de fichier txt donc pas d'instruments !")
            print("    Morceau suivant ....\n\n")
            self.instruments = None
            self.loop = 0

    def set_players(self):
        """Crée les players pour chaque canal
        Les drums ne sont pas sur le channel 9, complique et sert à rien

        la font i est sur le canal i
        for i in range(len(self.instruments)):
        self.instruments = [[0, 12, 5], [0, 0, 1]]
                            [bank,
                               bank_number = instrument,
                                                     font]
        """

        if self.instruments:
            i = 0
            for instrument in self.instruments:
                channel = int(instrument[2])
                bank = int(instrument[0])
                bank_number = int(instrument[1])
                self.players[channel] = OneInstrumentPlayer(
                    self.fonts, channel, bank, bank_number)
                i += 1

        print("Nombre de player:", len(self.players))

    def create_trackbar(self):
        """
        thresh            min 0 max 1
        hier_thresh       min 0 max 1
        nms               min 0 max 1
        """

        self.reglage_img = np.zeros((100, 600, 3), np.uint8)
        # #self.reglage_img = put_text(self.reglage_img,
        # #self.filename,
        # #(10, 50),
        # #size=0.8,
        # #thickness=2)

        cv2.createTrackbar('threshold_', 'Reglage', 0, 100,
                           self.onChange_thresh)
        cv2.createTrackbar('hier_thresh', 'Reglage', 0, 100,
                           self.onChange_hier_thresh)
        cv2.createTrackbar('nms_____', 'Reglage', 0, 100, self.onChange_nms)

    def set_init_tackbar_position(self):
        """setTrackbarPos(trackbarname, winname, pos) -> None"""

        cv2.setTrackbarPos('threshold_', 'Reglage', self.thresh)
        cv2.setTrackbarPos('hier_thresh', 'Reglage', self.hier_thresh)
        cv2.setTrackbarPos('nms_____', 'Reglage', self.nms)

    def onChange_thresh(self, thresh):
        """min=1 max=100 step=1 default=0.5"""
        if thresh == 0: thresh = 5
        if thresh == 100: thresh = 95
        self.thresh = int(thresh)
        self.save_change('play_letters', 'thresh', self.thresh)

    def onChange_hier_thresh(self, hier_thresh):
        """min=1 max=100 step=1 default=0.5"""
        if hier_thresh == 0: hier_thresh = 5
        if hier_thresh == 100: hier_thresh = 95
        self.hier_thresh = int(hier_thresh)
        self.save_change('play_letters', 'hier_thresh', self.hier_thresh)

    def onChange_nms(self, nms):
        """min=1 max=100 step=1 default=0.5"""
        if nms == 0: nms = 5
        if nms == 100: nms = 95
        self.nms = int(nms)
        self.save_change('play_letters', 'nms', self.nms)

    def save_change(self, section, key, value):
        lp.save_config(section, key, value)

    def get_sorted_shot_list(self):

        images = self.mt.get_all_files_list(self.images_directory, ".jpg")

        shot_list = [0] * len(images)

        # Récup du numéro le plus petit, les numéros ensuite se suivent
        mini = 10000000
        for image in images:
            nbr = int(image.split("/")[-1].split("_")[-1][:-4])
            if nbr < mini:
                mini = nbr

        # Tri des images
        n = 0
        for image in images:
            # Si de 500 à 1500
            # ../play_letters/s_j_to_i_1243.jpg devient s_j_to_i_1243.jpg
            nbr = int(image.split("/")[-1].split("_")[-1][:-4])  # 1243
            shot_list[nbr - mini] = image

        return shot_list

    def get_all_shot(self):
        """Charge en mémoire toutes les images du dossiers à lire par l'IA"""

        print("\n\nChargement de toutes les images en RAM. Patience ...\n\n")

        all_shot = []
        for shot_file in self.shot_list:
            img = cv2.imread(shot_file)
            all_shot.append(img)

        return all_shot

    def notes_cleaning(self, notes):
        # Suppression des doublons
        clean_notes = []
        for note in notes:
            if note not in clean_notes:
                clean_notes.append(note)

        # Validation des notes
        new_notes = []
        for font, note, vol in notes:
            # self.instruments = [[0, 12, 5], [0, 0, 1]]
            all_fonts = []
            for inst in self.instruments:
                all_fonts.append(int(inst[2]))
            if font not in all_fonts:
                font = None

            # note 1 à 127
            if note < 1 or note > 127:
                note = None

            # ## Volume 0 à 127:
            # #if vol > 127: vol = 127
            # #if vol < 0: vol = 0
            # Le volume est forcé à 127
            vol = 127

            if font is not None:
                if note:
                    new_notes.append([font, note, vol])

        return new_notes

    def play_notes(self, notes):
        """new_notes = [(police, note, volume), ...] = [(5, 124, 127), ... ]
        la police n'est pas le player
        self.players[i].thread_dict[key] = 0
        """

        new_notes = self.notes_cleaning(notes)

        # Notes en en_cours ******************************************
        en_cours = []
        # key=note, val=thread en cours 0 ou 1
        for k, v in self.players.items():
            for key, val in self.players[k].thread_dict.items():
                if val != 0:
                    en_cours.append((k, key))
        # #print("en_cours:", en_cours)

        # Fin des notes qui ne sont plus en en_cours *****************
        # notes = [(player, note, volume), ...]
        # en_cours = [(player, note), ... ]
        for ec in en_cours:
            player, note = ec
            ssss = [player, note, 127]  # list et non tuple !!
            if ssss not in new_notes:
                self.players[player].thread_dict[note] = 0
                # #print("Fin de:", player, note)

        # Lancement des nouvelles notes ******************************
        for player, note, vol in new_notes:
            if (player, note) not in en_cours:
                # #print("nouvelle", player, note)
                self.players[player].thread_play_note(note, 127)  # vol)

    def save_all_notes(self):
        """
        /bla...bla/play_letters_shot_jpg_3/bob_sheriff
        to
        /bla...bla/play_letters_shot_jpg_3/bob_sheriff_data.json
        """

        if not self.weights:
            json_name = self.images_directory + "_" + str(self.essai) + ".json"
        else:
            # Bidouille non générale
            a = len("/media/serge/BACKUP/play_letters_shot/pl_shot_14_jpg/")
            name = self.images_directory[a:] + "_"
            # les fichiers sont dans 1 sous dossier indice
            indice = str(self.get_weights_file_indice())
            doss = "/media/serge/BACKUP/play_letters_shot/pl_shot_14_jpg/test/"
            json_name = doss + indice + "/" + name + str(self.essai) + ".json"

        with open(json_name, 'w') as f_out:
            json.dump(self.all_notes, f_out)
        f_out.close()
        print('Enregistrement de:', json_name)

    def put_titre(self, image):
        """Insère le titre si i"""

        if self.titre:
            filename = self.filename
            filename = filename.replace("f_", "")
            filename = filename.replace("_", " ")
            filename = filename.replace("-", " ")
            image = put_text(image, filename, (10, 50), size=0.5, thickness=1)
        return image

    def apply_k(self, k, i):
        # Space pour morceau suivant et attente
        if k == 32:
            self.loop = 0

        # Affichage du titre si "i"
        if k == ord('i'):  # 105:
            if not self.titre:
                self.titre = 1
            else:
                self.titre = 0

        # Echap pour finir le script python
        if k == 27:
            os._exit(0)

        # Gestion de la fin du morceaux
        if i == len(self.shot_list):
            self.loop = 0

    def detect(self):
        """FPS = 40 sur GTX1060"""

        i = 0
        fps = 0
        t_init = time.time()
        tempo = 1
        t_tempo = time.time()

        # Si pas d'image, on passe la boucle
        if not self.all_shot:
            self.loop = 0

        while self.loop:
            black_image = self.black_image.copy()
            # Récup d'une image
            img = self.all_shot[i]

            # ## Capture des positions des sliders
            # #self.thresh = cv2.getTrackbarPos('threshold_','Reglage')
            # #self.hier_thresh = cv2.getTrackbarPos('hier_thresh','Reglage')
            # #self.nms = cv2.getTrackbarPos('nms','Reglage')

            # #img_resized = cv2.resize(img,
            # #(darknet.network_width(self.netMain),
            # #darknet.network_height(self.netMain)),
            # #interpolation=cv2.INTER_LINEAR)

            darknet.copy_image_from_bytes(self.darknet_image, img.tobytes())

            detections_l = darknet.detect_image(self.netMain, self.metaMain,
                                                self.darknet_image,
                                                self.thresh / 100,
                                                self.hier_thresh / 100,
                                                self.nms / 100)

            # Application des détections dans l'image
            image, letters = cvDrawBoxes(detections_l, img)
            notes = letters_to_notes(letters)
            self.play_notes(notes)

            # Ajout des notes pour enregistrement à la fin
            if self.save:
                self.all_notes.append(notes)

            # Insertion du titre
            image = self.put_titre(image)

            if not self.fullscreen:
                img = cv2.resize(image, (600, 600),
                                 interpolation=cv2.INTER_LINEAR)
            else:
                # gray[y1:y2, x1:x2] 162:578
                # 1440/900 = 1.6
                # #a = (self.screen[0]/self.screen[1] -1) / 2
                # #x1 = int(a*416)
                # #x2 = x1 + 416
                # #y1 = 0
                # #y2 = 416
                # #black_image[y1:y2, x1:x2] = image
                img = image  # black_image

            img = put_text(img,
                           str(self.fps), (10, 100),
                           size=0.5,
                           thickness=1)

            # Affichage
            cv2.imshow('Letters', img)  # image)
            # Affichage des trackbars
            cv2.imshow('Reglage', self.reglage_img)

            # Comptage
            i += 1  # prochaine image
            fps += 1
            ta = time.time()

            # Pour fps = 40 soit ta - t_tempo = 0.025
            # 0.035 pour fps = 40, 0.052 pour fps = 30
            tempo = int(1000 * (0.052 - (ta - t_tempo)))
            if tempo < 1:
                tempo = 1
            t_tempo = ta

            if ta > t_init + 1:
                self.fps = fps
                # #print("FPS =", round(fps, 1))
                t_init = time.time()
                fps = 0

            k = cv2.waitKey(tempo)
            self.apply_k(k, i)

        cv2.destroyAllWindows()

        # Libération de la mémoire GPU
        if self.gpu:
            self.free_network(self.netMain)

        # Enregistrement des notes
        if self.save:
            self.save_all_notes()

        # Fin des fluidsynth
        for k, v in self.players.items():
            self.players[k].stop_audio()
        time.sleep(0.3)
예제 #9
0
class BlurAndConvert:

    def __init__(self):
        self.mt = MyTools()
        self.blur_min = CONF["play_letters_shot"]["blur_min"]
        self.blur_max = CONF["play_letters_shot"]["blur_max"]
        self.size = CONF["play_letters_shot"]["shot_size"]

        # Dossiers
        self.shot = CONF["play_letters_shot"]["pl_shot"]
        print("Dossier play_letters:", self.shot)
        self.shot_jpg = self.shot + "_jpg"
        print("Dossier play_letters jpg:", self.shot_jpg)
        self.create_shot_jpg_dir()

        # Liste des sous-dossiers avec le dossier play_letters_shot
        self.sub_directories_list = [x[0] for x in os.walk(self.shot)]
        print("Liste des sous-répertoires:", self.sub_directories_list)
        self.create_sub_directories()

        # Copie des txt
        self.copy_all_txt()
        
        # Images png
        self.all_png_files = self.mt.get_all_files_list(self.shot, '.png')
        print("Nombre de fichiers à convertir:", len(self.all_png_files))
        if len(self.all_png_files) == 0:
            print("\n\nPas d'images à convertir")
            print("Créer les images avant !")
            os._exit(0)

        # Exécution du script flou puis save
        self.save_to_jpg()

    def copy_all_txt(self):
        """
        /bla...bla/play_letters_shot/bob_sherif/instruments.txt
        to
        /bla...bla/play_letters_shot_jpg_6/bob_sherif/instruments.txt
        """
        
        # Tous les txt
        txts = self.mt.get_all_files_list(self.shot, '.txt')

        for txt in txts:
            dst = txt.replace(self.shot, self.shot_jpg)
            # Copie du fichier txt des png dans les jpg
            copyfile(txt, dst)

    def create_shot_jpg_dir(self):
        
        print("Dossier pl_shot_jpg:", self.shot_jpg)
        # Si le dossier n'existe pas, je le crée
        self.mt.create_directory(self.shot_jpg)

    def create_sub_directories(self):
        """Création des sous dossiers."""

        for sd in self.sub_directories_list:
            if sd != self.shot:
                print("Sous répertoire en png:", sd)
                # Soustraction du chemin de shot_dir
                shot_dir = Path(self.shot)
                a = str(sd).replace(str(shot_dir), "")
                # Ajout du chemin de jpg_dir
                b = Path(str(self.shot_jpg) + a)
                print("Sous répertoire en jpg:", b)
                self.mt.create_directory(b)

    def apply_blur(self, img):

        blur = random.randint(self.blur_min, self.blur_max)
        if blur != 0:
            img = cv2.blur(img, (blur, blur))
        return img

    def save_to_jpg(self):
        n = 0
        
        for png in self.all_png_files:
            if n % 100 == 0 and n != 0:
                a = len(self.all_png_files)
                print("Nombre de fichiers convertis:", n, "sur", a)
            n += 1
            # print(png)
            
            # Lecture de png
            img = cv2.imread(png)

            # Retaillage avec size de letters.ini
            img = cv2.resize(img, (self.size, self.size), interpolation=cv2.INTER_AREA)
            
            # Flou
            img = self.apply_blur(img)

            # On travaille avec Path
            png_path = Path(png)
            jpg_path = self.get_jpg_name(png_path)  # PosixPath

            # Ecriture de l'image jpg, cv2 prend seulement path en str
            cv2.imwrite(str(jpg_path), img,
                                       [int(cv2.IMWRITE_JPEG_QUALITY),
                                       100])

            # On prend son temps
            sleep(0.01)

        print("Nombre de fichiers convertis:", n)
        
    def get_jpg_name(self, png_path):
        """ png = str
        png = str(self.shot)     + /25/shot_4126.png = str
        jpg = str(self.shot_jpg) + /25/shot_4126.jpg = str
        """

        # Soustraction du chemin de shot_dir
        a = str(png_path).replace(str(self.shot), "")
        # Ajout du chemin de jpg_dir
        b = Path(str(self.shot_jpg) + a)

        # Changement de l'extension
        jpg_path = b.with_suffix(".jpg")

        return jpg_path
예제 #10
0
class TtftoPng:

    def __init__(self, size):
        self.size = size
        self.tools = MyTools()

        # 10 polices possible seulement
        self.colors = COLORS
        self.color_num = 0
        
        # Create pngs directory
        self.tools.create_directory("./pngs")
        
        # Dict des dossiers avec ttf
        self.ttf_list = self.get_ttfs()
        
        # Création des sous dossiers dans ./pngs 
        self.create_sub_directories()

    def convert_ttfs(self):
        """Convertit tous les ttfs"""
        
        for rep in self.ttf_list:
            # récup du ttf
            ttf = self.tools.get_all_files_list(rep, 'ttf')
            print("Conversion de:", rep)
            self.convert_ttf(rep, ttf)
            self.color_num += 1
            
    def convert_ttf(self, rep, ttf):
        """Convertit un ttf"""
        
        for l in LETTRES:
            l = l.upper()
            self.convert_letter(l, rep, ttf)
            l = l.lower()
            self.convert_letter(l, rep, ttf)
        # #for c in CHIFFRES:
            # #self.convert_letter(c, rep, ttf)            
            
    def convert_letter(self, letter, rep, ttf):
        """Convertit une lettre
        Conversion de:  ./ttfs/southern/Southern.ttf
        lettre:  A
        dans: ./pngs/southern/
        command convert -background none -fill black -font
        ./ttfs/southern/Southern.ttf -pointsize 300 -write ./pngs/southern/
        label:"A" A.png
        """

        #print("Conversion de {}".format(letter))
        
        filename = "./pngs" + rep[6:] + "/" + letter + ".png"

        if len(ttf) > 0:
            font = "./" + ttf[0]
            # remplacement espace dans le nom,
            # mais dossier ne doit pas avoir d'espace
            font = font.replace(' ', '\\ ')
            color = self.colors[self.color_num]
            
            # #print(  "Conversion de: ", font,
                    # #" lettre: ", letter,
                    # #" dans: ", filename,
                    # #"color", color)

            command = 'convert -background none -fill {4} -font {3} \
                       -pointsize {1} label:"{0}" {2}'.format(  letter,
                                                                self.size,
                                                                filename,
                                                                font,
                                                                color)
            #print("command", command)
            
            subprocess.call(command, shell=True)
        
    def create_sub_directories(self):
        """"Création des sous dossiers dans ./pngs"""
        
        for d in self.ttf_list:
            parts = d.split("/")
            self.tools.create_directory("./pngs/" + parts[-1])
            
    def get_ttfs(self):
        # Tous les fichiers ttf
        ttfs = self.tools.get_all_sub_directories("./ttfs")

        ttf_list  = []
        
        for subdir in ttfs:
            if subdir != "./ttfs":
                dd = self.tools.get_all_sub_directories(subdir)
                for d in dd:
                    if "MACOSX" not in d:
                        if subdir not in ttf_list:
                            ttf_list.append(subdir)
        return ttf_list