예제 #1
0
def get_str(text_file_list):
    mt = MyTools()
    text_str = ''
    for f in text_file_list:
        text = mt.read_file(f)
        text_str += text

    text_str = get_ascii(text_str)
    return text_str
예제 #2
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)