Advertisement
Guest User

Untitled

a guest
Dec 7th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.30 KB | None | 0 0
  1. import sys
  2. import subprocess
  3. import cv2
  4. import time
  5. import numpy as np
  6. import os
  7. from best_fit import fit
  8. from rectangle import Rectangle
  9. from note import Note
  10. from random import randint
  11. #from midiutil.MidiFile3 import MIDIFile
  12. from midiutil import MIDIFile
  13.  
  14. staff_files = [
  15. "resources/template/staff3.png",
  16. "resources/template/staff2.png",
  17. "resources/template/staff.png"]
  18. quarter_files = [
  19. "resources/template/quarter.png",
  20. "resources/template/solid-note.png"]
  21. sharp_files = [
  22. "resources/template/sharp.png"]
  23. flat_files = [
  24. "resources/template/flat-line.png",
  25. "resources/template/flat-space.png" ]
  26. half_files = [
  27. "resources/template/half-space.png",
  28. "resources/template/half-note-line.png",
  29. "resources/template/half-line.png",
  30. "resources/template/half-note-space.png"]
  31. whole_files = [
  32. "resources/template/whole-space.png",
  33. "resources/template/whole-note-line.png",
  34. "resources/template/whole-line.png",
  35. "resources/template/whole-note-space.png"]
  36.  
  37. staff_imgs = [cv2.imread(staff_file, 0) for staff_file in staff_files]
  38. quarter_imgs = [cv2.imread(quarter_file, 0) for quarter_file in quarter_files]
  39. sharp_imgs = [cv2.imread(sharp_files, 0) for sharp_files in sharp_files]
  40. flat_imgs = [cv2.imread(flat_file, 0) for flat_file in flat_files]
  41. half_imgs = [cv2.imread(half_file, 0) for half_file in half_files]
  42. whole_imgs = [cv2.imread(whole_file, 0) for whole_file in whole_files]
  43.  
  44. staff_lower, staff_upper, staff_thresh = 50, 150, 0.77
  45. sharp_lower, sharp_upper, sharp_thresh = 50, 150, 0.70
  46. flat_lower, flat_upper, flat_thresh = 50, 150, 0.77
  47. quarter_lower, quarter_upper, quarter_thresh = 50, 150, 0.70
  48. half_lower, half_upper, half_thresh = 50, 150, 0.70
  49. whole_lower, whole_upper, whole_thresh = 50, 150, 0.70
  50.  
  51.  
  52. def locate_images(img, templates, start, stop, threshold):
  53. locations, scale = fit(img, templates, start, stop, threshold)
  54. img_locations = []
  55. for i in range(len(templates)):
  56. w, h = templates[i].shape[::-1]
  57. w *= scale
  58. h *= scale
  59. img_locations.append([Rectangle(pt[0], pt[1], w, h) for pt in zip(*locations[i][::-1])])
  60. return img_locations
  61.  
  62. def merge_recs(recs, threshold):
  63. filtered_recs = []
  64. while len(recs) > 0:
  65. r = recs.pop(0)
  66. recs.sort(key=lambda rec: rec.distance(r))
  67. merged = True
  68. while(merged):
  69. merged = False
  70. i = 0
  71. for _ in range(len(recs)):
  72. if r.overlap(recs[i]) > threshold or recs[i].overlap(r) > threshold:
  73. r = r.merge(recs.pop(i))
  74. merged = True
  75. elif recs[i].distance(r) > r.w/2 + recs[i].w/2:
  76. break
  77. else:
  78. i += 1
  79. filtered_recs.append(r)
  80. return filtered_recs
  81.  
  82. def open_file(path):
  83. cmd = {'linux':'eog', 'win32':'explorer', 'darwin':'open'}[sys.platform]
  84. subprocess.run([cmd, path])
  85.  
  86. if __name__ == "__main__":
  87. img_file = sys.argv[1]
  88. to_save = sys.argv[2]
  89. img = cv2.imread(img_file, 0)
  90. img_gray = img
  91. #cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  92. img = cv2.cvtColor(img_gray,cv2.COLOR_GRAY2RGB)
  93. ret,img_gray = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)
  94. img_width, img_height = img_gray.shape[::-1]
  95.  
  96. note_coord_file = open(os.path.join(to_save, 'note_coords'),'w') #GW
  97. note_file = open(os.path.join(to_save, 'note_file'),'w') #GW
  98.  
  99. print("Matching staff image...")
  100. sys.stdout.flush()
  101. staff_recs = locate_images(img_gray, staff_imgs, staff_lower, staff_upper, staff_thresh)
  102.  
  103. print("Filtering weak staff matches...")
  104. sys.stdout.flush()
  105. staff_recs = [j for i in staff_recs for j in i]
  106. heights = [r.y for r in staff_recs] + [0]
  107. histo = [heights.count(i) for i in range(0, max(heights) + 1)]
  108. avg = np.mean(list(set(histo)))
  109. staff_recs = [r for r in staff_recs if histo[r.y] > avg]
  110.  
  111. print("Merging staff image results...")
  112. sys.stdout.flush()
  113. staff_recs = merge_recs(staff_recs, 0.01)
  114. # staff_recs_img = img.copy()
  115. # for r in staff_recs:
  116. # r.draw(staff_recs_img, (0, 0, 255), 2)
  117. # cv2.imwrite('staff_recs_img.png', staff_recs_img)
  118. # open_file('staff_recs_img.png')
  119.  
  120. print("Discovering staff locations...")
  121. sys.stdout.flush()
  122. staff_boxes = merge_recs([Rectangle(0, r.y, img_width, r.h) for r in staff_recs], 0.01)
  123. # staff_boxes_img = img.copy()
  124. # for r in staff_boxes:
  125. # r.draw(staff_boxes_img, (0, 0, 255), 2)
  126. # cv2.imwrite('staff_boxes_img.png', staff_boxes_img)
  127. # open_file('staff_boxes_img.png')
  128.  
  129. print("Matching sharp image...")
  130. sys.stdout.flush()
  131. sharp_recs = locate_images(img_gray, sharp_imgs, sharp_lower, sharp_upper, sharp_thresh)
  132.  
  133. print("Merging sharp image results...")
  134. sys.stdout.flush()
  135. sharp_recs = merge_recs([j for i in sharp_recs for j in i], 0.5)
  136. # sharp_recs_img = img.copy()
  137. # for r in sharp_recs:
  138. # r.draw(sharp_recs_img, (0, 0, 255), 2)
  139. # cv2.imwrite('sharp_recs_img.png', sharp_recs_img)
  140. # open_file('sharp_recs_img.png')
  141.  
  142. print("Matching flat image...")
  143. sys.stdout.flush()
  144. flat_recs = locate_images(img_gray, flat_imgs, flat_lower, flat_upper, flat_thresh)
  145.  
  146. print("Merging flat image results...")
  147. sys.stdout.flush()
  148. flat_recs = merge_recs([j for i in flat_recs for j in i], 0.5)
  149. # flat_recs_img = img.copy()
  150. # for r in flat_recs:
  151. # r.draw(flat_recs_img, (0, 0, 255), 2)
  152. # cv2.imwrite('flat_recs_img.png', flat_recs_img)
  153. # open_file('flat_recs_img.png')
  154.  
  155. print("Matching quarter image...")
  156. sys.stdout.flush()
  157. quarter_recs = locate_images(img_gray, quarter_imgs, quarter_lower, quarter_upper, quarter_thresh)
  158.  
  159. print("Merging quarter image results...")
  160. sys.stdout.flush()
  161. quarter_recs = merge_recs([j for i in quarter_recs for j in i], 0.5)
  162. # quarter_recs_img = img.copy()
  163. # for r in quarter_recs:
  164. # r.draw(quarter_recs_img, (0, 0, 255), 2)
  165. # cv2.imwrite('quarter_recs_img.png', quarter_recs_img)
  166. # open_file('quarter_recs_img.png')
  167.  
  168. print("Matching half image...")
  169. sys.stdout.flush()
  170. half_recs = locate_images(img_gray, half_imgs, half_lower, half_upper, half_thresh)
  171.  
  172. print("Merging half image results...")
  173. sys.stdout.flush()
  174. half_recs = merge_recs([j for i in half_recs for j in i], 0.5)
  175. # half_recs_img = img.copy()
  176. # for r in half_recs:
  177. # r.draw(half_recs_img, (0, 0, 255), 2)
  178. # cv2.imwrite('half_recs_img.png', half_recs_img)
  179. # open_file('half_recs_img.png')
  180.  
  181. print("Matching whole image...")
  182. sys.stdout.flush()
  183. whole_recs = locate_images(img_gray, whole_imgs, whole_lower, whole_upper, whole_thresh)
  184.  
  185. print("Merging whole image results...")
  186. sys.stdout.flush()
  187. whole_recs = merge_recs([j for i in whole_recs for j in i], 0.5)
  188. # whole_recs_img = img.copy()
  189. # for r in whole_recs:
  190. # r.draw(whole_recs_img, (0, 0, 255), 2)
  191. # cv2.imwrite('whole_recs_img.png', whole_recs_img)
  192. # open_file('whole_recs_img.png')
  193.  
  194. note_groups = []
  195. for box in staff_boxes:
  196. staff_sharps = [Note(r, "sharp", box)
  197. for r in sharp_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0]
  198. staff_flats = [Note(r, "flat", box)
  199. for r in flat_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0]
  200. quarter_notes = [Note(r, "4,8", box, staff_sharps, staff_flats)
  201. for r in quarter_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0]
  202. half_notes = [Note(r, "2", box, staff_sharps, staff_flats)
  203. for r in half_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0]
  204. whole_notes = [Note(r, "1", box, staff_sharps, staff_flats)
  205. for r in whole_recs if abs(r.middle[1] - box.middle[1]) < box.h*5.0/8.0]
  206. staff_notes = quarter_notes + half_notes + whole_notes
  207. staff_notes.sort(key=lambda n: n.rec.x)
  208. staffs = [r for r in staff_recs if r.overlap(box) > 0]
  209. staffs.sort(key=lambda r: r.x)
  210. # note_color = (randint(0, 255), randint(0, 255), randint(0, 255))
  211. note_group = []
  212. i = 0; j = 0;
  213. while(i < len(staff_notes)):
  214. if (staff_notes[i].rec.x > staffs[j].x and j < len(staffs)):
  215. r = staffs[j]
  216. j += 1;
  217. if len(note_group) > 0:
  218. note_groups.append(note_group)
  219. note_group = []
  220. # note_color = (randint(0, 255), randint(0, 255), randint(0, 255))
  221. else:
  222. note_group.append(staff_notes[i])
  223. note_coord_file.write(staff_notes[i].rec.to_string() + "\n") #Write note's coord to a file
  224. note_file.write(staff_notes[i].note + "\n") #Write note to a file
  225. # staff_notes[i].rec.draw(img, note_color, 2)
  226. i += 1
  227. note_groups.append(note_group)
  228.  
  229. note_coord_file.close()
  230. note_file.close()
  231.  
  232. # for r in staff_boxes:
  233. # r.draw(img, (0, 0, 255), 2)
  234. # for r in sharp_recs:
  235. # r.draw(img, (0, 0, 255), 2)
  236. # flat_recs_img = img.copy()
  237. # for r in flat_recs:
  238. # r.draw(img, (0, 0, 255), 2)
  239.  
  240. # cv2.imwrite('res.png', img)
  241. # open_file('res.png')
  242.  
  243. # for note_group in note_groups:
  244. # print([ note.note + " " + note.sym for note in note_group])
  245.  
  246. midi = MIDIFile(1)
  247.  
  248. track = 0
  249. time = 0
  250. channel = 0
  251. volume = 100
  252.  
  253. midi.addTrackName(track, time, "Track")
  254. midi.addTempo(track, time, 140)
  255.  
  256. for note_group in note_groups:
  257. duration = None
  258. for note in note_group:
  259. note_type = note.sym
  260. if note_type == "1":
  261. duration = 4
  262. elif note_type == "2":
  263. duration = 2
  264. elif note_type == "4,8":
  265. duration = 1 if len(note_group) == 1 else 0.5
  266. pitch = note.pitch
  267. midi.addNote(track,channel,pitch,time,duration,volume)
  268. time += duration
  269.  
  270. midi.addNote(track,channel,pitch,time,4,0)
  271.  
  272. # And write it to disk.
  273. path = os.path.join(to_save, 'output.mid')
  274. binfile = open(path, 'wb')
  275. midi.writeFile(binfile)
  276. binfile.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement