From 7fa497a39ca748160c5747b5c3ad5c5b02169423 Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Fri, 30 May 2025 16:29:02 +0300 Subject: [PATCH 1/8] Included SheetVision FORK finally... --- main.py | 263 +++++++++++++++++++++++++++----------------------------- 1 file changed, 128 insertions(+), 135 deletions(-) diff --git a/main.py b/main.py index b1e0af5..52c0eed 100644 --- a/main.py +++ b/main.py @@ -1,36 +1,41 @@ +import os import sys -import subprocess + + +script_dir = os.path.dirname(os.path.abspath(__file__)) +os.chdir(script_dir) +sys.path.insert(0, script_dir) + import cv2 -import time import numpy as np from best_fit import fit from rectangle import Rectangle from note import Note from random import randint -from midiutil.MidiFile3 import MIDIFile staff_files = [ - "resources/template/staff2.png", + "resources/template/staff2.png", "resources/template/staff.png"] quarter_files = [ - "resources/template/quarter.png", + "resources/template/quarter.png", "resources/template/solid-note.png"] sharp_files = [ "resources/template/sharp.png"] flat_files = [ - "resources/template/flat-line.png", - "resources/template/flat-space.png" ] + "resources/template/flat-line.png", + "resources/template/flat-space.png"] half_files = [ - "resources/template/half-space.png", + "resources/template/half-space.png", "resources/template/half-note-line.png", - "resources/template/half-line.png", + "resources/template/half-line.png", "resources/template/half-note-space.png"] whole_files = [ - "resources/template/whole-space.png", + "resources/template/whole-space.png", "resources/template/whole-note-line.png", - "resources/template/whole-line.png", + "resources/template/whole-line.png", "resources/template/whole-note-space.png"] + staff_imgs = [cv2.imread(staff_file, 0) for staff_file in staff_files] quarter_imgs = [cv2.imread(quarter_file, 0) for quarter_file in quarter_files] sharp_imgs = [cv2.imread(sharp_files, 0) for sharp_files in sharp_files] @@ -38,12 +43,13 @@ half_imgs = [cv2.imread(half_file, 0) for half_file in half_files] whole_imgs = [cv2.imread(whole_file, 0) for whole_file in whole_files] -staff_lower, staff_upper, staff_thresh = 50, 150, 0.77 -sharp_lower, sharp_upper, sharp_thresh = 50, 150, 0.70 -flat_lower, flat_upper, flat_thresh = 50, 150, 0.77 -quarter_lower, quarter_upper, quarter_thresh = 50, 150, 0.70 -half_lower, half_upper, half_thresh = 50, 150, 0.70 -whole_lower, whole_upper, whole_thresh = 50, 150, 0.70 + +kernel = np.array([[0, -1, 0], + [-1, 5, -1], + [0, -1, 0]]) +kernel2 = np.array([[-1, -1, -1], + [0, 0, 0], + [1, 1, 1]]) def locate_images(img, templates, start, stop, threshold): @@ -56,140 +62,151 @@ def locate_images(img, templates, start, stop, threshold): img_locations.append([Rectangle(pt[0], pt[1], w, h) for pt in zip(*locations[i][::-1])]) return img_locations + def merge_recs(recs, threshold): filtered_recs = [] while len(recs) > 0: r = recs.pop(0) recs.sort(key=lambda rec: rec.distance(r)) merged = True - while(merged): + while (merged): merged = False i = 0 for _ in range(len(recs)): if r.overlap(recs[i]) > threshold or recs[i].overlap(r) > threshold: r = r.merge(recs.pop(i)) merged = True - elif recs[i].distance(r) > r.w/2 + recs[i].w/2: + elif recs[i].distance(r) > r.w / 2 + recs[i].w / 2: break else: i += 1 filtered_recs.append(r) return filtered_recs -def open_file(path): - cmd = {'linux':'eog', 'win32':'explorer', 'darwin':'open'}[sys.platform] - subprocess.run([cmd, path]) -if __name__ == "__main__": - img_file = sys.argv[1:][0] +def SheetVision(img_file): img = cv2.imread(img_file, 0) - img_gray = img#cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - img = cv2.cvtColor(img_gray,cv2.COLOR_GRAY2RGB) - ret,img_gray = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY) + img_gray0 = img # cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + img_gray = cv2.filter2D(img_gray0, -1, kernel) + img_staff = cv2.filter2D(img_gray0, -1, kernel2) + img_staff = cv2.bitwise_not(img_staff) + # cv2.imwrite('staff_recs_img.png', img_staff) + img = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB) + ret, img_gray = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) img_width, img_height = img_gray.shape[::-1] - print("Matching staff image...") - staff_recs = locate_images(img_gray, staff_imgs, staff_lower, staff_upper, staff_thresh) + staff_lower, staff_upper, staff_thresh = 50, 150, 0.77 # * (np.sqrt(img_width * img_height) / 1000) + sharp_lower, sharp_upper, sharp_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) + flat_lower, flat_upper, flat_thresh = 50, 150, 0.77 # * (np.sqrt(img_width * img_height) / 1000) + quarter_lower, quarter_upper, quarter_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) + half_lower, half_upper, half_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) + whole_lower, whole_upper, whole_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) - print("Filtering weak staff matches...") + # print("Matching staff image...") + staff_recs = locate_images(img_staff, staff_imgs, staff_lower, staff_upper, staff_thresh) + + # print("Filtering weak staff matches...") staff_recs = [j for i in staff_recs for j in i] heights = [r.y for r in staff_recs] + [0] histo = [heights.count(i) for i in range(0, max(heights) + 1)] avg = np.mean(list(set(histo))) staff_recs = [r for r in staff_recs if histo[r.y] > avg] - print("Merging staff image results...") + # print("Merging staff image results...") staff_recs = merge_recs(staff_recs, 0.01) - staff_recs_img = img.copy() - for r in staff_recs: - r.draw(staff_recs_img, (0, 0, 255), 2) - cv2.imwrite('staff_recs_img.png', staff_recs_img) - open_file('staff_recs_img.png') + # staff_recs_img = img.copy() + # for r in staff_recs: + # r.draw(staff_recs_img, (0, 0, 255), 2) + # cv2.imwrite('staff_recs_img.png', staff_recs_img) + # open_file('staff_recs_img.png') - print("Discovering staff locations...") + # print("Discovering staff locations...") staff_boxes = merge_recs([Rectangle(0, r.y, img_width, r.h) for r in staff_recs], 0.01) - staff_boxes_img = img.copy() - for r in staff_boxes: - r.draw(staff_boxes_img, (0, 0, 255), 2) - cv2.imwrite('staff_boxes_img.png', staff_boxes_img) - open_file('staff_boxes_img.png') - - print("Matching sharp image...") + # staff_boxes_img = img.copy() + # for r in staff_boxes: + # r.draw(staff_boxes_img, (0, 0, 255), 2) + # cv2.imwrite('staff_boxes_img.png', staff_boxes_img) + # open_file('staff_boxes_img.png') + + # print("Matching sharp image...") sharp_recs = locate_images(img_gray, sharp_imgs, sharp_lower, sharp_upper, sharp_thresh) - print("Merging sharp image results...") + # print("Merging sharp image results...") sharp_recs = merge_recs([j for i in sharp_recs for j in i], 0.5) - sharp_recs_img = img.copy() - for r in sharp_recs: - r.draw(sharp_recs_img, (0, 0, 255), 2) - cv2.imwrite('sharp_recs_img.png', sharp_recs_img) - open_file('sharp_recs_img.png') + # sharp_recs_img = img.copy() + # for r in sharp_recs: + # r.draw(sharp_recs_img, (0, 0, 255), 2) + # cv2.imwrite('sharp_recs_img.png', sharp_recs_img) + # open_file('sharp_recs_img.png') - print("Matching flat image...") + # print("Matching flat image...") flat_recs = locate_images(img_gray, flat_imgs, flat_lower, flat_upper, flat_thresh) - print("Merging flat image results...") + # print("Merging flat image results...") flat_recs = merge_recs([j for i in flat_recs for j in i], 0.5) - flat_recs_img = img.copy() - for r in flat_recs: - r.draw(flat_recs_img, (0, 0, 255), 2) - cv2.imwrite('flat_recs_img.png', flat_recs_img) - open_file('flat_recs_img.png') + # flat_recs_img = img.copy() + # for r in flat_recs: + # r.draw(flat_recs_img, (0, 0, 255), 2) + # cv2.imwrite('flat_recs_img.png', flat_recs_img) + # open_file('flat_recs_img.png') - print("Matching quarter image...") + # print("Matching quarter image...") quarter_recs = locate_images(img_gray, quarter_imgs, quarter_lower, quarter_upper, quarter_thresh) - print("Merging quarter image results...") + # print("Merging quarter image results...") quarter_recs = merge_recs([j for i in quarter_recs for j in i], 0.5) - quarter_recs_img = img.copy() - for r in quarter_recs: - r.draw(quarter_recs_img, (0, 0, 255), 2) - cv2.imwrite('quarter_recs_img.png', quarter_recs_img) - open_file('quarter_recs_img.png') + # quarter_recs_img = img.copy() + # for r in quarter_recs: + # r.draw(quarter_recs_img, (0, 0, 255), 2) + # cv2.imwrite('quarter_recs_img.png', quarter_recs_img) + # open_file('quarter_recs_img.png') - print("Matching half image...") + # print("Matching half image...") half_recs = locate_images(img_gray, half_imgs, half_lower, half_upper, half_thresh) - print("Merging half image results...") + # print("Merging half image results...") half_recs = merge_recs([j for i in half_recs for j in i], 0.5) - half_recs_img = img.copy() - for r in half_recs: - r.draw(half_recs_img, (0, 0, 255), 2) - cv2.imwrite('half_recs_img.png', half_recs_img) - open_file('half_recs_img.png') + # half_recs_img = img.copy() + # for r in half_recs: + # r.draw(half_recs_img, (0, 0, 255), 2) + # cv2.imwrite('half_recs_img.png', half_recs_img) + # open_file('half_recs_img.png') - print("Matching whole image...") + # print("Matching whole image...") whole_recs = locate_images(img_gray, whole_imgs, whole_lower, whole_upper, whole_thresh) - print("Merging whole image results...") + # print("Merging whole image results...") whole_recs = merge_recs([j for i in whole_recs for j in i], 0.5) - whole_recs_img = img.copy() - for r in whole_recs: - r.draw(whole_recs_img, (0, 0, 255), 2) - cv2.imwrite('whole_recs_img.png', whole_recs_img) - open_file('whole_recs_img.png') + # whole_recs_img = img.copy() + # for r in whole_recs: + # r.draw(whole_recs_img, (0, 0, 255), 2) + # cv2.imwrite('whole_recs_img.png', whole_recs_img) + # open_file('whole_recs_img.png') note_groups = [] for box in staff_boxes: - staff_sharps = [Note(r, "sharp", box) - for r in sharp_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0] - staff_flats = [Note(r, "flat", box) - for r in flat_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0] - quarter_notes = [Note(r, "4,8", box, staff_sharps, staff_flats) - for r in quarter_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0] - half_notes = [Note(r, "2", box, staff_sharps, staff_flats) - for r in half_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0] - whole_notes = [Note(r, "1", box, staff_sharps, staff_flats) - for r in whole_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0] + staff_sharps = [Note(r, "sharp", box) + for r in sharp_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + staff_flats = [Note(r, "flat", box) + for r in flat_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + quarter_notes = [Note(r, "4,8", box, staff_sharps, staff_flats) + for r in quarter_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + half_notes = [Note(r, "2", box, staff_sharps, staff_flats) + for r in half_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + whole_notes = [Note(r, "1", box, staff_sharps, staff_flats) + for r in whole_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] staff_notes = quarter_notes + half_notes + whole_notes + if len(staff_notes) == 0: + continue staff_notes.sort(key=lambda n: n.rec.x) staffs = [r for r in staff_recs if r.overlap(box) > 0] staffs.sort(key=lambda r: r.x) note_color = (randint(0, 255), randint(0, 255), randint(0, 255)) note_group = [] - i = 0; j = 0; - while(i < len(staff_notes)): - if (staff_notes[i].rec.x > staffs[j].x and j < len(staffs)): + i = 0; + j = 0; + while (i < len(staff_notes)): + if (j < len(staffs) and staff_notes[i].rec.x > staffs[j].x): r = staffs[j] j += 1; if len(note_group) > 0: @@ -202,47 +219,23 @@ def open_file(path): i += 1 note_groups.append(note_group) - for r in staff_boxes: - r.draw(img, (0, 0, 255), 2) - for r in sharp_recs: - r.draw(img, (0, 0, 255), 2) - flat_recs_img = img.copy() - for r in flat_recs: - r.draw(img, (0, 0, 255), 2) - - cv2.imwrite('res.png', img) - open_file('res.png') - - for note_group in note_groups: - print([ note.note + " " + note.sym for note in note_group]) - - midi = MIDIFile(1) - - track = 0 - time = 0 - channel = 0 - volume = 100 - - midi.addTrackName(track, time, "Track") - midi.addTempo(track, time, 140) - - for note_group in note_groups: - duration = None - for note in note_group: - note_type = note.sym - if note_type == "1": - duration = 4 - elif note_type == "2": - duration = 2 - elif note_type == "4,8": - duration = 1 if len(note_group) == 1 else 0.5 - pitch = note.pitch - midi.addNote(track,channel,pitch,time,duration,volume) - time += duration - - midi.addNote(track,channel,pitch,time,4,0) - # And write it to disk. - binfile = open("output.mid", 'wb') - midi.writeFile(binfile) - binfile.close() - open_file('output.mid') + # for r in staff_boxes: + # r.draw(img, (0, 0, 255), 2) + # for r in sharp_recs: + # r.draw(img, (0, 0, 255), 2) + # flat_recs_img = img.copy() + # for r in flat_recs: + # r.draw(img, (0, 0, 255), 2) + + # cv2.imwrite('res.png', img) + # open_file('res.png') + name = os.path.basename(img_file) + name = os.path.splitext(name)[0] + with open(f"{name}.txt", "w") as f: + for note_group in note_groups: + notes = [note.note for note in note_group] + for note in notes: + f.write(note) + f.write("\n") + + print(f"done page") From 5d0222f152832186c1dae1be16392bb822ba6356 Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Fri, 30 May 2025 16:35:29 +0300 Subject: [PATCH 2/8] Included SheetVision FORK finally... finally... --- best_fit.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/best_fit.py b/best_fit.py index 7e3be47..5f0517c 100644 --- a/best_fit.py +++ b/best_fit.py @@ -1,5 +1,5 @@ import cv2 -import matplotlib.pyplot as plt +# import matplotlib.pyplot as plt import numpy as np def fit(img, templates, start_percent, stop_percent, threshold): @@ -8,11 +8,11 @@ def fit(img, templates, start_percent, stop_percent, threshold): best_locations = [] best_scale = 1 - plt.axis([0, 2, 0, 1]) - plt.show(block=False) - - x = [] - y = [] + # plt.axis([0, 2, 0, 1]) + # plt.show(block=False) + # + # x = [] + # y = [] for scale in [i/100.0 for i in range(start_percent, stop_percent + 1, 3)]: locations = [] location_count = 0 @@ -23,18 +23,18 @@ def fit(img, templates, start_percent, stop_percent, threshold): result = np.where(result >= threshold) location_count += len(result[0]) locations += [result] - print("scale: {0}, hits: {1}".format(scale, location_count)) - x.append(location_count) - y.append(scale) - plt.plot(y, x) - plt.pause(0.00001) + # print("scale: {0}, hits: {1}".format(scale, location_count)) + # x.append(location_count) + # y.append(scale) + # plt.plot(y, x) + # plt.pause(0.00001) if (location_count > best_location_count): best_location_count = location_count best_locations = locations best_scale = scale - plt.axis([0, 2, 0, best_location_count]) + # plt.axis([0, 2, 0, best_location_count]) elif (location_count < best_location_count): pass - plt.close() + # plt.close() return best_locations, best_scale \ No newline at end of file From 18c90997bb24bc23fc742a0a421a7ea99f4196a2 Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Tue, 10 Jun 2025 15:12:03 +0300 Subject: [PATCH 3/8] Successfully applied the Computer Vision algorithm by using thresholds adjusted to each template and applying a clustering algorithm. Tweak needed to improve a bit recognition of anything but quarters and staves --- best_fit.py | 27 +++++- main.py | 249 +++++++++++++++++++++++++++++++++------------------- note.py | 22 ++++- 3 files changed, 205 insertions(+), 93 deletions(-) diff --git a/best_fit.py b/best_fit.py index 5f0517c..13b9b70 100644 --- a/best_fit.py +++ b/best_fit.py @@ -1,6 +1,8 @@ import cv2 # import matplotlib.pyplot as plt import numpy as np +from sklearn.cluster import KMeans + def fit(img, templates, start_percent, stop_percent, threshold): img_width, img_height = img.shape[::-1] @@ -20,7 +22,29 @@ def fit(img, templates, start_percent, stop_percent, threshold): template = cv2.resize(template, None, fx = scale, fy = scale, interpolation = cv2.INTER_CUBIC) result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) - result = np.where(result >= threshold) + + scores = result[result >= threshold].reshape(-1, 1) # all relevant scores + + if len(scores) < 2: + continue + kmeans = KMeans(n_clusters=2, random_state=0).fit(scores) + + # Get cluster with higher mean (strong matches) + cluster_labels = kmeans.labels_ + means = kmeans.cluster_centers_ + + strong_cluster = np.argmax(means) + adaptive_threshold = np.mean(scores[cluster_labels == strong_cluster]) + result = np.where(result >= adaptive_threshold) + # import matplotlib.pyplot as plt + + # plt.hist(scores.flatten(), bins=50, color='blue', alpha=0.7) + # plt.axvline(np.mean(scores[cluster_labels == strong_cluster]), color='red', label='Adaptive Threshold') + # plt.legend() + # plt.title("MatchTemplate Score Distribution") + # plt.xlabel("Score") + # plt.ylabel("Frequency") + # plt.show() location_count += len(result[0]) locations += [result] # print("scale: {0}, hits: {1}".format(scale, location_count)) @@ -36,5 +60,4 @@ def fit(img, templates, start_percent, stop_percent, threshold): elif (location_count < best_location_count): pass # plt.close() - return best_locations, best_scale \ No newline at end of file diff --git a/main.py b/main.py index 52c0eed..af083e2 100644 --- a/main.py +++ b/main.py @@ -11,7 +11,6 @@ from best_fit import fit from rectangle import Rectangle from note import Note -from random import randint staff_files = [ "resources/template/staff2.png", @@ -59,7 +58,10 @@ def locate_images(img, templates, start, stop, threshold): w, h = templates[i].shape[::-1] w *= scale h *= scale - img_locations.append([Rectangle(pt[0], pt[1], w, h) for pt in zip(*locations[i][::-1])]) + try: + img_locations.append([Rectangle(pt[0], pt[1], w, h) for pt in zip(*locations[i][::-1])]) + except IndexError: + pass return img_locations @@ -95,12 +97,16 @@ def SheetVision(img_file): ret, img_gray = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) img_width, img_height = img_gray.shape[::-1] - staff_lower, staff_upper, staff_thresh = 50, 150, 0.77 # * (np.sqrt(img_width * img_height) / 1000) - sharp_lower, sharp_upper, sharp_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) - flat_lower, flat_upper, flat_thresh = 50, 150, 0.77 # * (np.sqrt(img_width * img_height) / 1000) - quarter_lower, quarter_upper, quarter_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) - half_lower, half_upper, half_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) - whole_lower, whole_upper, whole_thresh = 50, 150, 0.70 # * (np.sqrt(img_width * img_height) / 1000) + + name = os.path.basename(img_file) + name = os.path.splitext(name)[0] + + staff_lower, staff_upper, staff_thresh = 50, 150, 0.5 # * (np.sqrt(img_width * img_height) / 1000) + sharp_lower, sharp_upper, sharp_thresh = 50, 150, 0.6 # * (np.sqrt(img_width * img_height) / 1000) + flat_lower, flat_upper, flat_thresh = 50, 150, 0.65 # * (np.sqrt(img_width * img_height) / 1000) + quarter_lower, quarter_upper, quarter_thresh = 50, 150, 0.4 # * (np.sqrt(img_width * img_height) / 1000) + half_lower, half_upper, half_thresh = 50, 150, 0.55 # * (np.sqrt(img_width * img_height) / 1000) + whole_lower, whole_upper, whole_thresh = 50, 150, 0.6 # * (np.sqrt(img_width * img_height) / 1000) # print("Matching staff image...") staff_recs = locate_images(img_staff, staff_imgs, staff_lower, staff_upper, staff_thresh) @@ -114,18 +120,18 @@ def SheetVision(img_file): # print("Merging staff image results...") staff_recs = merge_recs(staff_recs, 0.01) - # staff_recs_img = img.copy() - # for r in staff_recs: - # r.draw(staff_recs_img, (0, 0, 255), 2) - # cv2.imwrite('staff_recs_img.png', staff_recs_img) + staff_recs_img = img.copy() + for r in staff_recs: + r.draw(staff_recs_img, (0, 0, 255), 2) + cv2.imwrite(f'staff_recs_img{name}.png', staff_recs_img) # open_file('staff_recs_img.png') # print("Discovering staff locations...") staff_boxes = merge_recs([Rectangle(0, r.y, img_width, r.h) for r in staff_recs], 0.01) - # staff_boxes_img = img.copy() - # for r in staff_boxes: - # r.draw(staff_boxes_img, (0, 0, 255), 2) - # cv2.imwrite('staff_boxes_img.png', staff_boxes_img) + staff_boxes_img = img.copy() + for r in staff_boxes: + r.draw(staff_boxes_img, (0, 0, 255), 2) + cv2.imwrite(f'staff_boxes_img{name}.png', staff_boxes_img) # open_file('staff_boxes_img.png') # print("Matching sharp image...") @@ -133,10 +139,10 @@ def SheetVision(img_file): # print("Merging sharp image results...") sharp_recs = merge_recs([j for i in sharp_recs for j in i], 0.5) - # sharp_recs_img = img.copy() - # for r in sharp_recs: - # r.draw(sharp_recs_img, (0, 0, 255), 2) - # cv2.imwrite('sharp_recs_img.png', sharp_recs_img) + sharp_recs_img = img.copy() + for r in sharp_recs: + r.draw(sharp_recs_img, (0, 0, 255), 2) + cv2.imwrite(f'sharp_recs_img{name}.png', sharp_recs_img) # open_file('sharp_recs_img.png') # print("Matching flat image...") @@ -144,10 +150,10 @@ def SheetVision(img_file): # print("Merging flat image results...") flat_recs = merge_recs([j for i in flat_recs for j in i], 0.5) - # flat_recs_img = img.copy() - # for r in flat_recs: - # r.draw(flat_recs_img, (0, 0, 255), 2) - # cv2.imwrite('flat_recs_img.png', flat_recs_img) + flat_recs_img = img.copy() + for r in flat_recs: + r.draw(flat_recs_img, (0, 0, 255), 2) + cv2.imwrite(f'flat_recs_img{name}.png', flat_recs_img) # open_file('flat_recs_img.png') # print("Matching quarter image...") @@ -155,10 +161,10 @@ def SheetVision(img_file): # print("Merging quarter image results...") quarter_recs = merge_recs([j for i in quarter_recs for j in i], 0.5) - # quarter_recs_img = img.copy() - # for r in quarter_recs: - # r.draw(quarter_recs_img, (0, 0, 255), 2) - # cv2.imwrite('quarter_recs_img.png', quarter_recs_img) + quarter_recs_img = img.copy() + for r in quarter_recs: + r.draw(quarter_recs_img, (0, 0, 255), 2) + cv2.imwrite(f'quarter_recs_img{name}.png', quarter_recs_img) # open_file('quarter_recs_img.png') # print("Matching half image...") @@ -166,10 +172,10 @@ def SheetVision(img_file): # print("Merging half image results...") half_recs = merge_recs([j for i in half_recs for j in i], 0.5) - # half_recs_img = img.copy() - # for r in half_recs: - # r.draw(half_recs_img, (0, 0, 255), 2) - # cv2.imwrite('half_recs_img.png', half_recs_img) + half_recs_img = img.copy() + for r in half_recs: + r.draw(half_recs_img, (0, 0, 255), 2) + cv2.imwrite(f'half_recs_img{name}.png', half_recs_img) # open_file('half_recs_img.png') # print("Matching whole image...") @@ -177,65 +183,132 @@ def SheetVision(img_file): # print("Merging whole image results...") whole_recs = merge_recs([j for i in whole_recs for j in i], 0.5) - # whole_recs_img = img.copy() - # for r in whole_recs: - # r.draw(whole_recs_img, (0, 0, 255), 2) - # cv2.imwrite('whole_recs_img.png', whole_recs_img) + whole_recs_img = img.copy() + for r in whole_recs: + r.draw(whole_recs_img, (0, 0, 255), 2) + cv2.imwrite(f'whole_recs_img{name}.png', whole_recs_img) # open_file('whole_recs_img.png') note_groups = [] - for box in staff_boxes: - staff_sharps = [Note(r, "sharp", box) - for r in sharp_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - staff_flats = [Note(r, "flat", box) - for r in flat_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - quarter_notes = [Note(r, "4,8", box, staff_sharps, staff_flats) - for r in quarter_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - half_notes = [Note(r, "2", box, staff_sharps, staff_flats) - for r in half_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - whole_notes = [Note(r, "1", box, staff_sharps, staff_flats) - for r in whole_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - staff_notes = quarter_notes + half_notes + whole_notes - if len(staff_notes) == 0: - continue - staff_notes.sort(key=lambda n: n.rec.x) - staffs = [r for r in staff_recs if r.overlap(box) > 0] - staffs.sort(key=lambda r: r.x) - note_color = (randint(0, 255), randint(0, 255), randint(0, 255)) - note_group = [] - i = 0; - j = 0; - while (i < len(staff_notes)): - if (j < len(staffs) and staff_notes[i].rec.x > staffs[j].x): - r = staffs[j] - j += 1; - if len(note_group) > 0: - note_groups.append(note_group) - note_group = [] - note_color = (randint(0, 255), randint(0, 255), randint(0, 255)) - else: - note_group.append(staff_notes[i]) - staff_notes[i].rec.draw(img, note_color, 2) - i += 1 - note_groups.append(note_group) - - # for r in staff_boxes: - # r.draw(img, (0, 0, 255), 2) - # for r in sharp_recs: - # r.draw(img, (0, 0, 255), 2) - # flat_recs_img = img.copy() - # for r in flat_recs: - # r.draw(img, (0, 0, 255), 2) - - # cv2.imwrite('res.png', img) - # open_file('res.png') - name = os.path.basename(img_file) - name = os.path.splitext(name)[0] + prev_note = None + no_num = lambda x: "" if x[-1] in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] else x[-1] with open(f"{name}.txt", "w") as f: - for note_group in note_groups: - notes = [note.note for note in note_group] - for note in notes: - f.write(note) - f.write("\n") + for b, box in enumerate(staff_boxes): + staff_sharps = [Note(r, "sharp", box) + for r in sharp_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + staff_flats = [Note(r, "flat", box) + for r in flat_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + quarter_notes = [Note(r, "4,8", box, staff_sharps, staff_flats) + for r in quarter_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + half_notes = [Note(r, "2", box, staff_sharps, staff_flats) + for r in half_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + whole_notes = [Note(r, "1", box, staff_sharps, staff_flats) + for r in whole_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + staff_notes = quarter_notes + half_notes + whole_notes + if len(staff_notes) == 0: + continue + if b + 1 < len(staff_boxes) and staff_boxes[b + 1].distance(box) -(staff_boxes[b + 1].h + box.h)/2 <= (staff_boxes[b + 1].h + box.h)/6: + staff_sharps = [Note(r, "sharp", staff_boxes[b + 1]) + for r in sharp_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + staff_flats = [Note(r, "flat", staff_boxes[b + 1]) + for r in flat_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + quarter_notes = [Note(r, "4,8", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef" ) + for r in quarter_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + half_notes = [Note(r, "2", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef") + for r in half_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + whole_notes = [Note(r, "1", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef") + for r in whole_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + temp_len = len(staff_notes) + staff_notes = staff_notes + quarter_notes + half_notes + whole_notes + if len(staff_notes) == temp_len: + staff_notes.sort(key=lambda n: n.rec.x) + for note in staff_notes: + if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) + f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + else: + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) + f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + prev_note = note + staff_notes.sort(key=lambda n: n.rec.x) + for note in staff_notes: + if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) + f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + else: + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) + f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + prev_note = note + continue + else: + staff_notes.sort(key=lambda n: n.rec.x) + for note in staff_notes: + if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) + f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + else: + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) + f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + prev_note = note + + # staffs = [r for r in staff_recs if r.overlap(box) > 0] + # staffs.sort(key=lambda r: r.x) + # for staff in staffs: + # print(staff.x, staff.y, staff.w, staff.h) + # for note in staff_notes: + # print(note.note, note.rec.x, note.rec.y) + # note_group = [] + # i = 0; + # j = 0; + # while (i < len(staff_notes)): + # if (j < len(staffs) and staff_notes[i].rec.x > staffs[j].x): + # r = staffs[j] + # j += 1; + # if len(note_group) > 0: + # note_groups.append(note_group) + # note_group = [] + # note_color = (randint(0, 255), randint(0, 255), randint(0, 255)) + # else: + # note_group.append(staff_notes[i]) + # staff_notes[i].rec.draw(img, note_color, 2) + # i += 1 + # note_groups.append(note_group) + # + # # for r in staff_boxes: + # # r.draw(img, (0, 0, 255), 2) + # # for r in sharp_recs: + # # r.draw(img, (0, 0, 255), 2) + # # flat_recs_img = img.copy() + # # for r in flat_recs: + # # r.draw(img, (0, 0, 255), 2) + # + # # cv2.imwrite('res.png', img) + # # open_file('res.png') + # name = os.path.basename(img_file) + # name = os.path.splitext(name)[0] + # with open(f"{name}.txt", "w") as f: + # for note_group in note_groups: + # notes = [note.note for note in note_group] + # for note in notes: + # f.write(note) + # f.write("\n") print(f"done page") diff --git a/note.py b/note.py index 0131d22..46e6bc4 100644 --- a/note.py +++ b/note.py @@ -1,4 +1,5 @@ from rectangle import Rectangle +import random note_step = 0.0625 @@ -24,17 +25,29 @@ 14 : ("c3", 48), 15 : ("b2", 47), 16 : ("a2", 45), - 17 : ("f2", 53), + 17 : ("g2", 43), + 18 : ("f2", 41), } class Note(object): - def __init__(self, rec, sym, staff_rec, sharp_notes = [], flat_notes = []): + def __init__(self, rec, sym, staff_rec, sharp_notes = [], flat_notes = [], unseen=None): self.rec = rec self.sym = sym middle = rec.y + (rec.h / 2.0) height = (middle - staff_rec.y) / staff_rec.h - note_def = note_defs[int(height/note_step + 0.5)] + if unseen == "f_clef": + try: + note_def = note_defs[int(height / note_step + 0.5) - 2] + except KeyError: + note_def = note_defs[int(height / note_step + 0.5)] + letter = note_def[0] + if letter[0] == "g": + note_def = ["e2", 3] + else: + note_def = ["d2", 3] + else: + note_def = note_defs[int(height/note_step + 0.5)] self.note = note_def[0] self.pitch = note_def[1] if any(n for n in sharp_notes if n.note[0] == self.note[0]): @@ -43,5 +56,8 @@ def __init__(self, rec, sym, staff_rec, sharp_notes = [], flat_notes = []): if any(n for n in flat_notes if n.note[0] == self.note[0]): self.note += "b" self.pitch -= 1 + # kinda retarded that i patch it up like this, but let's try anyways: + if self.note[:-2] == "#b": + self.note = self.note[-2:] From e73e97330a58645f2a18e84a5c36bbb8eb956247 Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Sat, 14 Jun 2025 07:29:50 +0300 Subject: [PATCH 4/8] Backup commit --- main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/main.py b/main.py index af083e2..d4465db 100644 --- a/main.py +++ b/main.py @@ -309,6 +309,4 @@ def SheetVision(img_file): # notes = [note.note for note in note_group] # for note in notes: # f.write(note) - # f.write("\n") - - print(f"done page") + # f.write("\n") \ No newline at end of file From 348f3b5c7520f88a60a5047b3a5de61ccbefc421 Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Sun, 15 Jun 2025 17:54:11 +0300 Subject: [PATCH 5/8] attempted to rewrite the code with ChatGPT --- main.py | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/main.py b/main.py index d4465db..d58b4b4 100644 --- a/main.py +++ b/main.py @@ -120,18 +120,18 @@ def SheetVision(img_file): # print("Merging staff image results...") staff_recs = merge_recs(staff_recs, 0.01) - staff_recs_img = img.copy() - for r in staff_recs: - r.draw(staff_recs_img, (0, 0, 255), 2) - cv2.imwrite(f'staff_recs_img{name}.png', staff_recs_img) + # staff_recs_img = img.copy() + # for r in staff_recs: + # r.draw(staff_recs_img, (0, 0, 255), 2) + # cv2.imwrite(f'staff_recs_img{name}.png', staff_recs_img) # open_file('staff_recs_img.png') # print("Discovering staff locations...") staff_boxes = merge_recs([Rectangle(0, r.y, img_width, r.h) for r in staff_recs], 0.01) - staff_boxes_img = img.copy() - for r in staff_boxes: - r.draw(staff_boxes_img, (0, 0, 255), 2) - cv2.imwrite(f'staff_boxes_img{name}.png', staff_boxes_img) + # staff_boxes_img = img.copy() + # for r in staff_boxes: + # r.draw(staff_boxes_img, (0, 0, 255), 2) + # cv2.imwrite(f'staff_boxes_img{name}.png', staff_boxes_img) # open_file('staff_boxes_img.png') # print("Matching sharp image...") @@ -139,10 +139,10 @@ def SheetVision(img_file): # print("Merging sharp image results...") sharp_recs = merge_recs([j for i in sharp_recs for j in i], 0.5) - sharp_recs_img = img.copy() - for r in sharp_recs: - r.draw(sharp_recs_img, (0, 0, 255), 2) - cv2.imwrite(f'sharp_recs_img{name}.png', sharp_recs_img) + # sharp_recs_img = img.copy() + # for r in sharp_recs: + # r.draw(sharp_recs_img, (0, 0, 255), 2) + # cv2.imwrite(f'sharp_recs_img{name}.png', sharp_recs_img) # open_file('sharp_recs_img.png') # print("Matching flat image...") @@ -150,10 +150,10 @@ def SheetVision(img_file): # print("Merging flat image results...") flat_recs = merge_recs([j for i in flat_recs for j in i], 0.5) - flat_recs_img = img.copy() - for r in flat_recs: - r.draw(flat_recs_img, (0, 0, 255), 2) - cv2.imwrite(f'flat_recs_img{name}.png', flat_recs_img) + # flat_recs_img = img.copy() + # for r in flat_recs: + # r.draw(flat_recs_img, (0, 0, 255), 2) + # cv2.imwrite(f'flat_recs_img{name}.png', flat_recs_img) # open_file('flat_recs_img.png') # print("Matching quarter image...") @@ -161,10 +161,10 @@ def SheetVision(img_file): # print("Merging quarter image results...") quarter_recs = merge_recs([j for i in quarter_recs for j in i], 0.5) - quarter_recs_img = img.copy() - for r in quarter_recs: - r.draw(quarter_recs_img, (0, 0, 255), 2) - cv2.imwrite(f'quarter_recs_img{name}.png', quarter_recs_img) + # quarter_recs_img = img.copy() + # for r in quarter_recs: + # r.draw(quarter_recs_img, (0, 0, 255), 2) + # cv2.imwrite(f'quarter_recs_img{name}.png', quarter_recs_img) # open_file('quarter_recs_img.png') # print("Matching half image...") @@ -172,10 +172,10 @@ def SheetVision(img_file): # print("Merging half image results...") half_recs = merge_recs([j for i in half_recs for j in i], 0.5) - half_recs_img = img.copy() - for r in half_recs: - r.draw(half_recs_img, (0, 0, 255), 2) - cv2.imwrite(f'half_recs_img{name}.png', half_recs_img) + # half_recs_img = img.copy() + # for r in half_recs: + # r.draw(half_recs_img, (0, 0, 255), 2) + # cv2.imwrite(f'half_recs_img{name}.png', half_recs_img) # open_file('half_recs_img.png') # print("Matching whole image...") @@ -183,10 +183,10 @@ def SheetVision(img_file): # print("Merging whole image results...") whole_recs = merge_recs([j for i in whole_recs for j in i], 0.5) - whole_recs_img = img.copy() - for r in whole_recs: - r.draw(whole_recs_img, (0, 0, 255), 2) - cv2.imwrite(f'whole_recs_img{name}.png', whole_recs_img) + # whole_recs_img = img.copy() + # for r in whole_recs: + # r.draw(whole_recs_img, (0, 0, 255), 2) + # cv2.imwrite(f'whole_recs_img{name}.png', whole_recs_img) # open_file('whole_recs_img.png') note_groups = [] From d3eab9522f7b29e41d0a9fa23d23eb87ad123c41 Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Mon, 16 Jun 2025 15:14:06 +0300 Subject: [PATCH 6/8] Small twiks --- main.py | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index d58b4b4..29df8d6 100644 --- a/main.py +++ b/main.py @@ -224,31 +224,31 @@ def SheetVision(img_file): staff_notes.sort(key=lambda n: n.rec.x) for note in staff_notes: if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) + temp = img_gray.copy() + cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + cv2.imshow(f"{note.note}", temp) + cv2.waitKey(0) f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") else: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) + temp = img_gray.copy() + cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + cv2.imshow(f"{note.note}", temp) + cv2.waitKey(0) f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") prev_note = note staff_notes.sort(key=lambda n: n.rec.x) for note in staff_notes: if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) + temp = img_gray.copy() + cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + cv2.imshow(f"{note.note}", temp) + cv2.waitKey(0) f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") else: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) + temp = img_gray.copy() + cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + cv2.imshow(f"{note.note}", temp) + cv2.waitKey(0) f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") prev_note = note continue @@ -256,16 +256,16 @@ def SheetVision(img_file): staff_notes.sort(key=lambda n: n.rec.x) for note in staff_notes: if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) + temp = img_gray.copy() + cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + cv2.imshow(f"{note.note}", temp) + cv2.waitKey(0) f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") else: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) + temp = img_gray.copy() + cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + cv2.imshow(f"{note.note}", temp) + cv2.waitKey(0) f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") prev_note = note From 6e23f302a4d90107a253ee44761e2cff9afcbed2 Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Wed, 18 Jun 2025 18:56:50 +0300 Subject: [PATCH 7/8] Revert "better gui, no more prints and unused code that's commented" This reverts commit 5979e829 --- main.py | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index 29df8d6..d58b4b4 100644 --- a/main.py +++ b/main.py @@ -224,31 +224,31 @@ def SheetVision(img_file): staff_notes.sort(key=lambda n: n.rec.x) for note in staff_notes: if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - temp = img_gray.copy() - cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - cv2.imshow(f"{note.note}", temp) - cv2.waitKey(0) + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") else: - temp = img_gray.copy() - cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - cv2.imshow(f"{note.note}", temp) - cv2.waitKey(0) + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") prev_note = note staff_notes.sort(key=lambda n: n.rec.x) for note in staff_notes: if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - temp = img_gray.copy() - cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - cv2.imshow(f"{note.note}", temp) - cv2.waitKey(0) + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") else: - temp = img_gray.copy() - cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - cv2.imshow(f"{note.note}", temp) - cv2.waitKey(0) + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") prev_note = note continue @@ -256,16 +256,16 @@ def SheetVision(img_file): staff_notes.sort(key=lambda n: n.rec.x) for note in staff_notes: if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - temp = img_gray.copy() - cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - cv2.imshow(f"{note.note}", temp) - cv2.waitKey(0) + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") else: - temp = img_gray.copy() - cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - cv2.imshow(f"{note.note}", temp) - cv2.waitKey(0) + # temp = img_gray.copy() + # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) + # cv2.imshow(f"{note.note}", temp) + # cv2.waitKey(0) f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") prev_note = note From 052813869a8d1a961fd8b53d1775feec43dbd5de Mon Sep 17 00:00:00 2001 From: ItayRimmler Date: Fri, 20 Jun 2025 21:37:31 +0300 Subject: [PATCH 8/8] I think I have done everything that wasn't done. The only thing I couldn't do is to automatically disable the filter of the mic. --- main.py | 140 +++++++++++++++++++++++++++----------------------------- 1 file changed, 68 insertions(+), 72 deletions(-) diff --git a/main.py b/main.py index d58b4b4..1ac709c 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,5 @@ +""" +""" import os import sys @@ -85,8 +87,21 @@ def merge_recs(recs, threshold): filtered_recs.append(r) return filtered_recs +NOTE_ORDER = ["c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b"] +NOTE_TO_INDEX = {note: i for i, note in enumerate(NOTE_ORDER)} + +def transpose_note(note, semitone_shift): + base_note = note[:-1] if note[-1].isdigit() else note # Strip number if exists + octave = int(note[-1]) if note[-1].isdigit() else 4 # default octave = 4 + index = NOTE_TO_INDEX[base_note] + new_index = index + semitone_shift + new_octave = octave + (new_index // 12) + new_note = NOTE_ORDER[new_index % 12] + return f"{new_note}{new_octave}" def SheetVision(img_file): + """ + """ img = cv2.imread(img_file, 0) img_gray0 = img # cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_gray = cv2.filter2D(img_gray0, -1, kernel) @@ -191,83 +206,64 @@ def SheetVision(img_file): note_groups = [] prev_note = None - no_num = lambda x: "" if x[-1] in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] else x[-1] - with open(f"{name}.txt", "w") as f: - for b, box in enumerate(staff_boxes): - staff_sharps = [Note(r, "sharp", box) - for r in sharp_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - staff_flats = [Note(r, "flat", box) - for r in flat_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - quarter_notes = [Note(r, "4,8", box, staff_sharps, staff_flats) - for r in quarter_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - half_notes = [Note(r, "2", box, staff_sharps, staff_flats) - for r in half_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - whole_notes = [Note(r, "1", box, staff_sharps, staff_flats) - for r in whole_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] - staff_notes = quarter_notes + half_notes + whole_notes - if len(staff_notes) == 0: - continue - if b + 1 < len(staff_boxes) and staff_boxes[b + 1].distance(box) -(staff_boxes[b + 1].h + box.h)/2 <= (staff_boxes[b + 1].h + box.h)/6: - staff_sharps = [Note(r, "sharp", staff_boxes[b + 1]) - for r in sharp_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] - staff_flats = [Note(r, "flat", staff_boxes[b + 1]) - for r in flat_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] - quarter_notes = [Note(r, "4,8", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef" ) - for r in quarter_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] - half_notes = [Note(r, "2", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef") - for r in half_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] - whole_notes = [Note(r, "1", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef") - for r in whole_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] - temp_len = len(staff_notes) - staff_notes = staff_notes + quarter_notes + half_notes + whole_notes - if len(staff_notes) == temp_len: + + for semitone_shift in range(12): + shifted_name = f"{name}__{semitone_shift}" + with open(f"{shifted_name}.txt", "w") as f: + for b, box in enumerate(staff_boxes): + staff_sharps = [Note(r, "sharp", box) + for r in sharp_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + staff_flats = [Note(r, "flat", box) + for r in flat_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + quarter_notes = [Note(r, "4,8", box, staff_sharps, staff_flats) + for r in quarter_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + half_notes = [Note(r, "2", box, staff_sharps, staff_flats) + for r in half_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + whole_notes = [Note(r, "1", box, staff_sharps, staff_flats) + for r in whole_recs if abs(r.middle[1] - box.middle[1]) < box.h * 5.0 / 8.0] + staff_notes = quarter_notes + half_notes + whole_notes + if len(staff_notes) == 0: + continue + if b + 1 < len(staff_boxes) and staff_boxes[b + 1].distance(box) -(staff_boxes[b + 1].h + box.h)/2 <= (staff_boxes[b + 1].h + box.h)/6: + staff_sharps = [Note(r, "sharp", staff_boxes[b + 1]) + for r in sharp_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + staff_flats = [Note(r, "flat", staff_boxes[b + 1]) + for r in flat_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + quarter_notes = [Note(r, "4,8", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef" ) + for r in quarter_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + half_notes = [Note(r, "2", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef") + for r in half_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + whole_notes = [Note(r, "1", staff_boxes[b + 1], staff_sharps, staff_flats, unseen="f_clef") + for r in whole_recs if abs(r.middle[1] - staff_boxes[b + 1].middle[1]) < staff_boxes[b + 1].h * 5.0 / 8.0] + temp_len = len(staff_notes) + staff_notes = staff_notes + quarter_notes + half_notes + whole_notes + if len(staff_notes) == temp_len: + staff_notes.sort(key=lambda n: n.rec.x) + for note in staff_notes: + transposed = transpose_note(note.note[0], semitone_shift) + if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: + f.write(" " + transposed) + else: + f.write("\n" + transposed) + prev_note = note + staff_notes.sort(key=lambda n: n.rec.x) + for note in staff_notes: + transposed = transpose_note(note.note[0], semitone_shift) + if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: + f.write(" " + transposed) + else: + f.write("\n" + transposed) + prev_note = note + continue + else: staff_notes.sort(key=lambda n: n.rec.x) for note in staff_notes: + transposed = transpose_note(note.note[0], semitone_shift) if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) - f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + f.write(" " + transposed) else: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) - f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") + f.write("\n" + transposed) prev_note = note - staff_notes.sort(key=lambda n: n.rec.x) - for note in staff_notes: - if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) - f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") - else: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) - f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") - prev_note = note - continue - else: - staff_notes.sort(key=lambda n: n.rec.x) - for note in staff_notes: - if prev_note and abs(prev_note.rec.x - note.rec.x) < 10: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) - f.write(" " + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") - else: - # temp = img_gray.copy() - # cv2.circle(temp, (note.rec.x, note.rec.y), 20, (0, 255, 0), 5) - # cv2.imshow(f"{note.note}", temp) - # cv2.waitKey(0) - f.write("\n" + f"{note.note[0]}")#{no_num(note.note[-1])}@({note.rec.x},{note.rec.y})") - prev_note = note # staffs = [r for r in staff_recs if r.overlap(box) > 0] # staffs.sort(key=lambda r: r.x)