修改midi2img库img2midi代码批量处理samples文件夹图片生成MIDI
修改后完整代码
from PIL import Image import numpy as np from music21 import instrument, note, chord, stream import os import sys lowerBoundNote = 21 def column2notes(column): notes = [] for i in range(len(column)): if column[i] > 255/2: notes.append(i+lowerBoundNote) return notes resolution = 0.25 def updateNotes(newNotes,prevNotes): res = {} for note in newNotes: if note in prevNotes: res[note] = prev_notes[note] + resolution else: res[note] = resolution return res def image2midi(image_path): with Image.open(image_path) as image: im_arr = np.fromstring(image.tobytes(), dtype=np.uint8) try: im_arr = im_arr.reshape((image.size[1], image.size[0])) except: im_arr = im_arr.reshape((image.size[1], image.size[0],3)) im_arr = np.dot(im_arr, [0.33, 0.33, 0.33]) """ convert the output from the prediction to notes and create a midi file from the notes """ offset = 0 output_notes = [] # create note and chord objects based on the values generated by the model prev_notes = updateNotes(im_arr.T[0,:],{}) for column in im_arr.T[1:,:]: notes = column2notes(column) # pattern is a chord notes_in_chord = notes old_notes = prev_notes.keys() for old_note in old_notes: if not old_note in notes_in_chord: new_note = note.Note(old_note,quarterLength=prev_notes[old_note]) new_note.storedInstrument = instrument.Piano() if offset - prev_notes[old_note] >= 0: new_note.offset = offset - prev_notes[old_note] output_notes.append(new_note) elif offset == 0: new_note.offset = offset output_notes.append(new_note) else: print(offset,prev_notes[old_note],old_note) prev_notes = updateNotes(notes_in_chord,prev_notes) # increase offset each iteration so that notes do not stack offset += resolution for old_note in prev_notes.keys(): new_note = note.Note(old_note,quarterLength=prev_notes[old_note]) new_note.storedInstrument = instrument.Piano() new_note.offset = offset - prev_notes[old_note] output_notes.append(new_note) prev_notes = updateNotes(notes_in_chord,prev_notes) midi_stream = stream.Stream(output_notes) # 优化文件名生成逻辑,适配所有常见图片后缀 img_filename = os.path.basename(image_path) midi_filename = os.path.splitext(img_filename)[0] + ".mid" midi_stream.write('midi', fp=midi_filename) if __name__ == "__main__": # 默认读取samples文件夹,也支持通过命令行参数指定其他文件夹路径 img_dir = sys.argv[1] if len(sys.argv) > 1 else "samples" # 支持的图片格式 support_ext = (".png", ".jpg", ".jpeg", ".bmp") # 遍历目录下所有文件 for filename in os.listdir(img_dir): if filename.lower().endswith(support_ext): img_path = os.path.join(img_dir, filename) print(f"正在处理:{img_path}") image2midi(img_path) print("所有图片处理完成")
修改说明
- 新增
os模块导入,用于目录遍历和文件路径处理 - 优化了MIDI文件名生成逻辑,不再仅支持jpeg格式,自动适配所有常见图片后缀
- 替换原有的单文件读取逻辑,默认自动遍历
samples目录下的所有符合格式的图片,也支持通过命令行参数指定其他图片文件夹路径 - 新增处理进度提示,控制台会打印当前正在处理的文件路径,处理完成后会给出提示
使用方法
直接在终端运行以下命令即可自动处理samples文件夹下的所有图片:
python img2midi.py
如果需要指定其他图片文件夹,也可以传入文件夹路径作为参数:
python img2midi.py 你的图片文件夹路径
内容的提问来源于stack exchange,提问作者mohamed mostapha
相关产品推荐
相关产品推荐

