CoolFace
Apppublic

Chickaboo/Advanced-MIDI-Renderer

sourceHugging Facecc-by-nc-4.0updated 4mo agoView on Hugging Face
1likes
TPLOTS.py1522 linesDownload Raw Back to root
1#! /usr/bin/python3
2
3r'''############################################################################
4################################################################################
5#
6#
7#	    Tegridy Plots Python Module (TPLOTS)
8#	    Version 1.0
9#
10#	    Project Los Angeles
11#
12#	    Tegridy Code 2025
13#
14#       https://github.com/asigalov61/tegridy-tools
15#
16#
17################################################################################
18#
19#       Copyright 2024 Project Los Angeles / Tegridy Code
20#
21#       Licensed under the Apache License, Version 2.0 (the "License");
22#       you may not use this file except in compliance with the License.
23#       You may obtain a copy of the License at
24#
25#           http://www.apache.org/licenses/LICENSE-2.0
26#
27#       Unless required by applicable law or agreed to in writing, software
28#       distributed under the License is distributed on an "AS IS" BASIS,
29#       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30#       See the License for the specific language governing permissions and
31#       limitations under the License.
32#
33################################################################################
34################################################################################
35#
36#       Critical dependencies
37#
38#       !pip install numpy==1.24.4
39#       !pip install scipy
40#       !pip install matplotlib
41#       !pip install networkx
42#       !pip3 install scikit-learn
43#
44################################################################################
45#
46#       Future critical dependencies
47#
48#       !pip install umap-learn
49#       !pip install alphashape
50#
51################################################################################
52'''
53
54################################################################################
55# Modules imports
56################################################################################
57
58import os
59from collections import Counter
60from itertools import groupby
61
62import numpy as np
63
64import networkx as nx
65
66from sklearn.manifold import TSNE
67from sklearn import metrics
68from sklearn.preprocessing import MinMaxScaler
69from sklearn.decomposition import PCA
70
71from scipy.ndimage import zoom
72from scipy.spatial import distance_matrix
73from scipy.sparse.csgraph import minimum_spanning_tree
74from scipy.stats import zscore
75
76import matplotlib.pyplot as plt
77from PIL import Image
78
79################################################################################
80# Constants
81################################################################################
82
83ALL_CHORDS_FULL = [[0], [0, 3], [0, 3, 5], [0, 3, 5, 8], [0, 3, 5, 9], [0, 3, 5, 10], [0, 3, 6],
84                  [0, 3, 6, 9], [0, 3, 6, 10], [0, 3, 7], [0, 3, 7, 10], [0, 3, 8], [0, 3, 9],
85                  [0, 3, 10], [0, 4], [0, 4, 6], [0, 4, 6, 9], [0, 4, 6, 10], [0, 4, 7],
86                  [0, 4, 7, 10], [0, 4, 8], [0, 4, 9], [0, 4, 10], [0, 5], [0, 5, 8], [0, 5, 9],
87                  [0, 5, 10], [0, 6], [0, 6, 9], [0, 6, 10], [0, 7], [0, 7, 10], [0, 8], [0, 9],
88                  [0, 10], [1], [1, 4], [1, 4, 6], [1, 4, 6, 9], [1, 4, 6, 10], [1, 4, 6, 11],
89                  [1, 4, 7], [1, 4, 7, 10], [1, 4, 7, 11], [1, 4, 8], [1, 4, 8, 11], [1, 4, 9],
90                  [1, 4, 10], [1, 4, 11], [1, 5], [1, 5, 8], [1, 5, 8, 11], [1, 5, 9],
91                  [1, 5, 10], [1, 5, 11], [1, 6], [1, 6, 9], [1, 6, 10], [1, 6, 11], [1, 7],
92                  [1, 7, 10], [1, 7, 11], [1, 8], [1, 8, 11], [1, 9], [1, 10], [1, 11], [2],
93                  [2, 5], [2, 5, 8], [2, 5, 8, 11], [2, 5, 9], [2, 5, 10], [2, 5, 11], [2, 6],
94                  [2, 6, 9], [2, 6, 10], [2, 6, 11], [2, 7], [2, 7, 10], [2, 7, 11], [2, 8],
95                  [2, 8, 11], [2, 9], [2, 10], [2, 11], [3], [3, 5], [3, 5, 8], [3, 5, 8, 11],
96                  [3, 5, 9], [3, 5, 10], [3, 5, 11], [3, 6], [3, 6, 9], [3, 6, 10], [3, 6, 11],
97                  [3, 7], [3, 7, 10], [3, 7, 11], [3, 8], [3, 8, 11], [3, 9], [3, 10], [3, 11],
98                  [4], [4, 6], [4, 6, 9], [4, 6, 10], [4, 6, 11], [4, 7], [4, 7, 10], [4, 7, 11],
99                  [4, 8], [4, 8, 11], [4, 9], [4, 10], [4, 11], [5], [5, 8], [5, 8, 11], [5, 9],
100                  [5, 10], [5, 11], [6], [6, 9], [6, 10], [6, 11], [7], [7, 10], [7, 11], [8],
101                  [8, 11], [9], [10], [11]]
102
103################################################################################
104
105CHORDS_TYPES = ['WHITE', 'BLACK', 'UNKNOWN', 'MIXED WHITE', 'MIXED BLACK', 'MIXED GRAY']
106
107################################################################################
108
109WHITE_NOTES = [0, 2, 4, 5, 7, 9, 11]
110
111################################################################################
112
113BLACK_NOTES = [1, 3, 6, 8, 10]
114
115################################################################################
116# Helper functions
117################################################################################
118
119def tones_chord_type(tones_chord, 
120                     return_chord_type_index=True,
121                     ):
122
123  """
124  Returns tones chord type
125  """
126
127  WN = WHITE_NOTES
128  BN = BLACK_NOTES
129  MX = WHITE_NOTES + BLACK_NOTES
130
131
132  CHORDS = ALL_CHORDS_FULL
133
134  tones_chord = sorted(tones_chord)
135
136  ctype = 'UNKNOWN'
137
138  if tones_chord in CHORDS:
139
140    if sorted(set(tones_chord) & set(WN)) == tones_chord:
141      ctype = 'WHITE'
142
143    elif sorted(set(tones_chord) & set(BN)) == tones_chord:
144      ctype = 'BLACK'
145
146    if len(tones_chord) > 1 and sorted(set(tones_chord) & set(MX)) == tones_chord:
147
148      if len(sorted(set(tones_chord) & set(WN))) == len(sorted(set(tones_chord) & set(BN))):
149        ctype = 'MIXED GRAY'
150
151      elif len(sorted(set(tones_chord) & set(WN))) > len(sorted(set(tones_chord) & set(BN))):
152        ctype = 'MIXED WHITE'
153
154      elif len(sorted(set(tones_chord) & set(WN))) < len(sorted(set(tones_chord) & set(BN))):
155        ctype = 'MIXED BLACK'
156
157  if return_chord_type_index:
158    return CHORDS_TYPES.index(ctype)
159
160  else:
161    return ctype
162
163###################################################################################
164
165def tone_type(tone, 
166              return_tone_type_index=True
167              ):
168
169  """
170  Returns tone type
171  """
172
173  tone = tone % 12
174
175  if tone in BLACK_NOTES:
176    if return_tone_type_index:
177      return CHORDS_TYPES.index('BLACK')
178    else:
179      return "BLACK"
180
181  else:
182    if return_tone_type_index:
183      return CHORDS_TYPES.index('WHITE')
184    else:
185      return "WHITE"
186
187###################################################################################
188
189def find_closest_points(points, return_points=True):
190
191  """
192  Find closest 2D points
193  """
194
195  coords = np.array(points)
196
197  num_points = coords.shape[0]
198  closest_matches = np.zeros(num_points, dtype=int)
199  distances = np.zeros((num_points, num_points))
200
201  for i in range(num_points):
202      for j in range(num_points):
203          if i != j:
204              distances[i, j] = np.linalg.norm(coords[i] - coords[j])
205          else:
206              distances[i, j] = np.inf
207
208  closest_matches = np.argmin(distances, axis=1)
209  
210  if return_points:
211    points_matches = coords[closest_matches].tolist()
212    return points_matches
213  
214  else:
215    return closest_matches.tolist()
216
217################################################################################
218
219def reduce_dimensionality_tsne(list_of_valies,
220                                n_comp=2,
221                                n_iter=5000,
222                                verbose=True
223                              ):
224
225  """
226  Reduces the dimensionality of the values using t-SNE.
227  """
228
229  vals = np.array(list_of_valies)
230
231  tsne = TSNE(n_components=n_comp,
232              n_iter=n_iter,
233              verbose=verbose)
234
235  reduced_vals = tsne.fit_transform(vals)
236
237  return reduced_vals.tolist()
238
239################################################################################
240
241def compute_mst_edges(similarity_scores_list):
242
243  """
244  Computes the Minimum Spanning Tree (MST) edges based on the similarity scores.
245  """
246  
247  num_tokens = len(similarity_scores_list[0])
248
249  graph = nx.Graph()
250
251  for i in range(num_tokens):
252      for j in range(i + 1, num_tokens):
253          weight = 1 - similarity_scores_list[i][j]
254          graph.add_edge(i, j, weight=weight)
255
256  mst = nx.minimum_spanning_tree(graph)
257
258  mst_edges = list(mst.edges(data=False))
259
260  return mst_edges
261
262################################################################################
263
264def square_binary_matrix(binary_matrix, 
265                         matrix_size=128,
266                         interpolation_order=5,
267                         return_square_matrix_points=False
268                         ):
269
270  """
271  Reduces an arbitrary binary matrix to a square binary matrix
272  """
273
274  zoom_factors = (matrix_size / len(binary_matrix), 1)
275
276  resized_matrix = zoom(binary_matrix, zoom_factors, order=interpolation_order)
277
278  resized_matrix = (resized_matrix > 0.5).astype(int)
279
280  final_matrix = np.zeros((matrix_size, matrix_size), dtype=int)
281  final_matrix[:, :resized_matrix.shape[1]] = resized_matrix
282
283  points = np.column_stack(np.where(final_matrix == 1)).tolist()
284
285  if return_square_matrix_points:
286    return points
287
288  else:
289    return resized_matrix
290
291################################################################################
292
293def square_matrix_points_colors(square_matrix_points):
294
295  """
296  Returns colors for square matrix points
297  """
298
299  cmap = generate_colors(12)
300
301  chords = []
302  chords_dict = set()
303  counts = []
304
305  for k, v in groupby(square_matrix_points, key=lambda x: x[0]):
306    pgroup = [vv[1] for vv in v]
307    chord = sorted(set(pgroup))
308    tchord = sorted(set([p % 12 for p in chord]))
309    chords_dict.add(tuple(tchord))
310    chords.append(tuple(tchord))
311    counts.append(len(pgroup))
312
313  chords_dict = sorted(chords_dict)
314
315  colors = []
316
317  for i, c in enumerate(chords):
318    colors.extend([cmap[round(sum(c) / len(c))]] * counts[i])
319
320  return colors
321
322################################################################################
323
324def hsv_to_rgb(h, s, v):
325
326  if s == 0.0:
327      return v, v, v
328
329  i = int(h*6.0)
330  f = (h*6.0) - i
331  p = v*(1.0 - s)
332  q = v*(1.0 - s*f)
333  t = v*(1.0 - s*(1.0-f))
334  i = i%6
335  
336  return [(v, t, p), (q, v, p), (p, v, t), (p, q, v), (t, p, v), (v, p, q)][i]
337
338################################################################################
339
340def generate_colors(n):
341  return [hsv_to_rgb(i/n, 1, 1) for i in range(n)]
342
343################################################################################
344
345def add_arrays(a, b):
346  return [sum(pair) for pair in zip(a, b)]
347
348################################################################################
349
350def calculate_similarities(lists_of_values, metric='cosine'):
351  return metrics.pairwise_distances(lists_of_values, metric=metric).tolist()
352
353################################################################################
354
355def get_tokens_embeddings(x_transformer_model):
356  return x_transformer_model.net.token_emb.emb.weight.detach().cpu().tolist()
357
358################################################################################
359
360def minkowski_distance_matrix(X, p=3):
361
362  X = np.array(X)
363
364  n = X.shape[0]
365  dist_matrix = np.zeros((n, n))
366
367  for i in range(n):
368      for j in range(n):
369          dist_matrix[i, j] = np.sum(np.abs(X[i] - X[j])**p)**(1/p)
370
371  return dist_matrix.tolist()
372
373################################################################################
374
375def robust_normalize(values):
376
377  values = np.array(values)
378  q1 = np.percentile(values, 25)
379  q3 = np.percentile(values, 75)
380  iqr = q3 - q1
381
382  filtered_values = values[(values >= q1 - 1.5 * iqr) & (values <= q3 + 1.5 * iqr)]
383
384  min_val = np.min(filtered_values)
385  max_val = np.max(filtered_values)
386  normalized_values = (values - min_val) / (max_val - min_val)
387
388  normalized_values = np.clip(normalized_values, 0, 1)
389
390  return normalized_values.tolist()
391
392################################################################################
393
394def min_max_normalize(values):
395
396  scaler = MinMaxScaler()
397
398  return scaler.fit_transform(values).tolist()
399
400################################################################################
401
402def remove_points_outliers(points, z_score_threshold=3):
403
404  points = np.array(points)
405
406  z_scores = np.abs(zscore(points, axis=0))
407
408  return points[(z_scores < z_score_threshold).all(axis=1)].tolist()
409
410################################################################################
411
412def generate_labels(lists_of_values, 
413                    return_indices_labels=False
414                    ):
415
416  ordered_indices = list(range(len(lists_of_values)))
417  ordered_indices_labels = [str(i) for i in ordered_indices]
418  ordered_values_labels = [str(lists_of_values[i]) for i in ordered_indices]
419
420  if return_indices_labels:
421    return ordered_indices_labels
422  
423  else:
424    return ordered_values_labels
425
426################################################################################
427
428def reduce_dimensionality_pca(list_of_values, n_components=2):
429
430  """
431  Reduces the dimensionality of the values using PCA.
432  """
433
434  pca = PCA(n_components=n_components)
435  pca_data = pca.fit_transform(list_of_values)
436  
437  return pca_data.tolist()
438
439def reduce_dimensionality_simple(list_of_values, 
440                                 return_means=True,
441                                 return_std_devs=True,
442                                 return_medians=False,
443                                 return_vars=False
444                                 ):
445  
446  '''
447  Reduces dimensionality of the values in a simple way
448  '''
449
450  array = np.array(list_of_values)
451  results = []
452
453  if return_means:
454      means = np.mean(array, axis=1)
455      results.append(means)
456
457  if return_std_devs:
458      std_devs = np.std(array, axis=1)
459      results.append(std_devs)
460
461  if return_medians:
462      medians = np.median(array, axis=1)
463      results.append(medians)
464
465  if return_vars:
466      vars = np.var(array, axis=1)
467      results.append(vars)
468
469  merged_results = np.column_stack(results)
470  
471  return merged_results.tolist()
472
473################################################################################
474
475def reduce_dimensionality_2d_distance(list_of_values, p=5):
476
477  '''
478  Reduces the dimensionality of the values using 2d distance
479  '''
480
481  values = np.array(list_of_values)
482
483  dist_matrix = distance_matrix(values, values, p=p)
484
485  mst = minimum_spanning_tree(dist_matrix).toarray()
486
487  points = []
488
489  for i in range(len(values)):
490      for j in range(len(values)):
491          if mst[i, j] > 0:
492              points.append([i, j])
493
494  return points
495
496################################################################################
497
498def normalize_to_range(values, n):
499    
500  min_val = min(values)
501  max_val = max(values)
502  
503  range_val = max_val - min_val
504  
505  normalized_values = [((value - min_val) / range_val * 2 * n) - n for value in values]
506  
507  return normalized_values
508
509################################################################################
510
511def reduce_dimensionality_simple_pca(list_of_values, n_components=2):
512
513  '''
514  Reduces the dimensionality of the values using simple PCA
515  '''
516
517  reduced_values = []
518
519  for l in list_of_values:
520
521    norm_values = [round(v * len(l)) for v in normalize_to_range(l, (n_components+1) // 2)]
522
523    pca_values = Counter(norm_values).most_common()
524    pca_values = [vv[0] / len(l) for vv in pca_values]
525    pca_values = pca_values[:n_components]
526    pca_values = pca_values + [0] * (n_components - len(pca_values))
527
528    reduced_values.append(pca_values)
529
530  return reduced_values
531
532################################################################################
533
534def filter_and_replace_values(list_of_values, 
535                              threshold, 
536                              replace_value, 
537                              replace_above_threshold=False
538                              ):
539
540  array = np.array(list_of_values)
541
542  modified_array = np.copy(array)
543  
544  if replace_above_threshold:
545    modified_array[modified_array > threshold] = replace_value
546  
547  else:
548    modified_array[modified_array < threshold] = replace_value
549  
550  return modified_array.tolist()
551
552################################################################################
553
554def find_shortest_constellation_path(points, 
555                                     start_point_idx, 
556                                     end_point_idx,
557                                     p=5,
558                                     return_path_length=False,
559                                     return_path_points=False,
560                                     ):
561
562    """
563    Finds the shortest path between two points of the points constellation
564    """
565
566    points = np.array(points)
567
568    dist_matrix = distance_matrix(points, points, p=p)
569
570    mst = minimum_spanning_tree(dist_matrix).toarray()
571
572    G = nx.Graph()
573
574    for i in range(len(points)):
575        for j in range(len(points)):
576            if mst[i, j] > 0:
577                G.add_edge(i, j, weight=mst[i, j])
578
579    path = nx.shortest_path(G, 
580                            source=start_point_idx, 
581                            target=end_point_idx, 
582                            weight='weight'
583                            )
584    
585    path_length = nx.shortest_path_length(G, 
586                                          source=start_point_idx, 
587                                          target=end_point_idx, 
588                                          weight='weight')
589        
590    path_points = points[np.array(path)].tolist()
591
592
593    if return_path_points:
594      return path_points
595
596    if return_path_length:
597      return path_length
598
599    return path
600
601################################################################################
602# Core functions
603################################################################################
604
605def plot_ms_SONG(ms_song,
606                  preview_length_in_notes=0,
607                  block_lines_times_list = None,
608                  plot_title='ms Song',
609                  max_num_colors=129, 
610                  drums_color_num=128, 
611                  plot_size=(11,4), 
612                  note_height = 0.75,
613                  show_grid_lines=False,
614                  return_plt = False,
615                  timings_multiplier=1,
616                  save_plt='',
617                  save_only_plt_image=True,
618                  save_transparent=False
619                  ):
620
621  '''ms SONG plot'''
622
623  notes = [s for s in ms_song if s[0] == 'note']
624
625  if (len(max(notes, key=len)) != 7) and (len(min(notes, key=len)) != 7):
626    print('The song notes do not have patches information')
627    print('Ploease add patches to the notes in the song')
628
629  else:
630
631    start_times = [(s[1] * timings_multiplier) / 1000 for s in notes]
632    durations = [(s[2]  * timings_multiplier) / 1000 for s in notes]
633    pitches = [s[4] for s in notes]
634    patches = [s[6] for s in notes]
635
636    colors = generate_colors(max_num_colors)
637    colors[drums_color_num] = (1, 1, 1)
638
639    pbl = (notes[preview_length_in_notes][1] * timings_multiplier) / 1000
640
641    fig, ax = plt.subplots(figsize=plot_size)
642
643    for start, duration, pitch, patch in zip(start_times, durations, pitches, patches):
644        rect = plt.Rectangle((start, pitch), duration, note_height, facecolor=colors[patch])
645        ax.add_patch(rect)
646
647    ax.set_xlim([min(start_times), max(add_arrays(start_times, durations))])
648    ax.set_ylim([min(pitches)-1, max(pitches)+1])
649
650    ax.set_facecolor('black')
651    fig.patch.set_facecolor('white')
652
653    if preview_length_in_notes > 0:
654      ax.axvline(x=pbl, c='white')
655
656    if block_lines_times_list:
657      for bl in block_lines_times_list:
658        ax.axvline(x=bl, c='white')
659           
660    if show_grid_lines:
661      ax.grid(color='white')
662
663    plt.xlabel('Time (s)', c='black')
664    plt.ylabel('MIDI Pitch', c='black')
665
666    plt.title(plot_title)
667
668    if save_plt != '':
669      if save_only_plt_image:
670        plt.axis('off')
671        plt.title('')
672        plt.savefig(save_plt, 
673                    transparent=save_transparent, 
674                    bbox_inches='tight', 
675                    pad_inches=0, 
676                    facecolor='black'
677                    )
678        plt.close()
679      
680      else:
681        plt.savefig(save_plt)
682        plt.close()
683
684    if return_plt:
685      return fig
686
687    plt.show()
688    plt.close()
689
690################################################################################
691
692def plot_square_matrix_points(list_of_points,
693                              list_of_points_colors,
694                              plot_size=(7, 7),
695                              point_size = 10,
696                              show_grid_lines=False,
697                              plot_title = 'Square Matrix Points Plot',
698                              return_plt=False,
699                              save_plt='',
700                              save_only_plt_image=True,
701                              save_transparent=False
702                              ):
703
704  '''Square matrix points plot'''
705
706  fig, ax = plt.subplots(figsize=plot_size)
707
708  ax.set_facecolor('black')
709
710  if show_grid_lines:
711    ax.grid(color='white')
712
713  plt.xlabel('Time Step', c='black')
714  plt.ylabel('MIDI Pitch', c='black')
715
716  plt.title(plot_title)
717
718  plt.scatter([p[0] for p in list_of_points], 
719              [p[1] for p in list_of_points], 
720              c=list_of_points_colors, 
721              s=point_size
722              )
723
724  if save_plt != '':
725    if save_only_plt_image:
726      plt.axis('off')
727      plt.title('')
728      plt.savefig(save_plt, 
729                  transparent=save_transparent, 
730                  bbox_inches='tight', 
731                  pad_inches=0, 
732                  facecolor='black'
733                  )
734      plt.close()
735    
736    else:
737      plt.savefig(save_plt)
738      plt.close()
739
740  if return_plt:
741    return fig
742
743  plt.show()
744  plt.close()
745
746################################################################################
747
748def plot_cosine_similarities(lists_of_values,
749                             plot_size=(7, 7),
750                             save_plot=''
751                            ):
752
753  """
754  Cosine similarities plot
755  """
756
757  cos_sim = metrics.pairwise_distances(lists_of_values, metric='cosine')
758
759  plt.figure(figsize=plot_size)
760
761  plt.imshow(cos_sim, cmap="inferno", interpolation="nearest")
762
763  im_ratio = cos_sim.shape[0] / cos_sim.shape[1]
764
765  plt.colorbar(fraction=0.046 * im_ratio, pad=0.04)
766
767  plt.xlabel("Index")
768  plt.ylabel("Index")
769
770  plt.tight_layout()
771
772  if save_plot != '':
773    plt.savefig(save_plot, bbox_inches="tight")
774    plt.close()
775
776  plt.show()
777  plt.close()
778
779################################################################################
780
781def plot_points_with_mst_lines(points, 
782                               points_labels, 
783                               points_mst_edges,
784                               plot_size=(20, 20),
785                               labels_size=24,
786                               save_plot=''
787                               ):
788
789  """
790  Plots 2D points with labels and MST lines.
791  """
792
793  plt.figure(figsize=plot_size)
794
795  for i, label in enumerate(points_labels):
796      plt.scatter(points[i][0], points[i][1])
797      plt.annotate(label, (points[i][0], points[i][1]), fontsize=labels_size)
798
799  for edge in points_mst_edges:
800      i, j = edge
801      plt.plot([points[i][0], points[j][0]], [points[i][1], points[j][1]], 'k-', alpha=0.5)
802
803  plt.title('Points Map with MST Lines', fontsize=labels_size)
804  plt.xlabel('X-axis', fontsize=labels_size)
805  plt.ylabel('Y-axis', fontsize=labels_size)
806
807  if save_plot != '':
808    plt.savefig(save_plot, bbox_inches="tight")
809    plt.close()
810
811  plt.show()
812
813  plt.close()
814
815################################################################################
816
817def plot_points_constellation(points, 
818                              points_labels,
819                              p=5,                              
820                              plot_size=(15, 15),
821                              labels_size=12,
822                              show_grid=False,
823                              save_plot=''
824                              ):
825
826  """
827  Plots 2D points constellation
828  """
829
830  points = np.array(points)
831
832  dist_matrix = distance_matrix(points, points, p=p)
833
834  mst = minimum_spanning_tree(dist_matrix).toarray()
835
836  plt.figure(figsize=plot_size)
837
838  plt.scatter(points[:, 0], points[:, 1], color='blue')
839
840  for i, label in enumerate(points_labels):
841      plt.annotate(label, (points[i, 0], points[i, 1]), 
842                   textcoords="offset points", 
843                   xytext=(0, 10), 
844                   ha='center',
845                   fontsize=labels_size
846                   )
847
848  for i in range(len(points)):
849      for j in range(len(points)):
850          if mst[i, j] > 0:
851              plt.plot([points[i, 0], points[j, 0]], [points[i, 1], points[j, 1]], 'k--')
852
853  plt.xlabel('X-axis', fontsize=labels_size)
854  plt.ylabel('Y-axis', fontsize=labels_size)
855  plt.title('2D Coordinates with Minimum Spanning Tree', fontsize=labels_size)
856
857  plt.grid(show_grid)
858
859  if save_plot != '':
860    plt.savefig(save_plot, bbox_inches="tight")
861    plt.close()
862
863  plt.show()
864
865  plt.close()
866
867################################################################################
868
869def binary_matrix_to_images(matrix, 
870                            step,
871                            overlap,
872                            output_folder='./Dataset/', 
873                            output_img_prefix='image', 
874                            output_img_ext='.png',
875                            save_to_array=False,
876                            verbose=True
877                            ):
878
879    if not save_to_array:
880
881      if verbose:
882        print('=' * 70)
883        print('Checking output folder dir...')
884
885      os.makedirs(os.path.dirname(output_folder), exist_ok=True)
886
887      if verbose:
888        print('Done!')
889
890    if verbose:
891      print('=' * 70)
892      print('Writing images...')
893
894    matrix = np.array(matrix, dtype=np.uint8)
895    
896    image_array = []
897    
898    for i in range(0, max(1, matrix.shape[0]), overlap):
899       
900        submatrix = matrix[i:i+step, :]
901
902        if submatrix.shape[0] < 128:
903          zeros_array = np.zeros((128-submatrix.shape[0], 128))
904          submatrix = np.vstack((submatrix, zeros_array))
905
906        img = Image.fromarray(submatrix * 255).convert('1')
907        
908        if save_to_array:
909          image_array.append(np.array(img))
910
911        else:
912          img.save(output_folder + output_img_prefix + '_' + str(matrix.shape[1]) + '_' + str(i).zfill(7) + output_img_ext)
913  
914    if verbose:
915      print('Done!')
916      print('=' * 70)
917      print('Saved', (matrix.shape[0] // min(step, overlap))+1, 'imges!')
918      print('=' * 70)
919
920    if save_to_array:
921        return np.array(image_array).tolist()
922
923################################################################################
924
925def images_to_binary_matrix(list_of_images):
926
927    image_array = np.array(list_of_images)
928   
929    original_matrix = []
930    
931    for img in image_array:
932
933        submatrix = np.array(img)
934        original_matrix.extend(submatrix.tolist())
935    
936    return original_matrix
937
938################################################################################
939
940def square_image_matrix(image_matrix,
941                        matrix_size=128,
942                        num_pca_components=5,
943                        filter_out_zero_rows=False,
944                        return_square_matrix_points=False
945                        ):
946
947  """
948  Reduces an arbitrary image matrix to a square image matrix
949  """
950
951  matrix = np.array(image_matrix)
952
953  if filter_out_zero_rows:
954    matrix = matrix[~np.all(matrix == 0, axis=1)]
955
956  target_rows = matrix_size
957
958  rows_per_group = matrix.shape[0] // target_rows
959
960  compressed_matrix = np.zeros((target_rows, matrix.shape[1]), dtype=np.int32)
961
962  for i in range(target_rows):
963      start_row = i * rows_per_group
964      end_row = (i + 1) * rows_per_group
965      group = matrix[start_row:end_row, :]
966      
967      pca = PCA(n_components=num_pca_components)
968      pca.fit(group)
969      
970      principal_component = np.mean(pca.components_, axis=0)
971      contributions = np.dot(group, principal_component)
972      selected_row_index = np.argmax(contributions)
973      
974      compressed_matrix[i, :] = group[selected_row_index, :]
975
976  if return_square_matrix_points:
977    filtered_matrix = compressed_matrix[~np.all(compressed_matrix == 0, axis=1)]
978
979    row_indexes, col_indexes = np.where(filtered_matrix != 0)
980    points = np.column_stack((row_indexes, filtered_matrix[row_indexes, col_indexes])).tolist()
981
982    return points
983
984  else:
985    return compressed_matrix.tolist()
986
987################################################################################
988
989def image_matrix_to_images(image_matrix,
990                           step,
991                           overlap,
992                           num_img_channels=3,
993                           output_folder='./Dataset/',
994                           output_img_prefix='image',
995                           output_img_ext='.png',
996                           save_to_array=False,
997                           verbose=True
998                           ):
999
1000    if num_img_channels > 1:
1001      n_mat_channels = 3
1002
1003    else:
1004      n_mat_channels = 1
1005
1006    if not save_to_array:
1007
1008      if verbose:
1009        print('=' * 70)
1010        print('Checking output folder dir...')
1011
1012      os.makedirs(os.path.dirname(output_folder), exist_ok=True)
1013
1014      if verbose:
1015        print('Done!')
1016
1017    if verbose:
1018      print('=' * 70)
1019      print('Writing images...')
1020
1021    matrix = np.array(image_matrix)
1022
1023    image_array = []
1024
1025    for i in range(0, max(1, matrix.shape[0]), overlap):
1026
1027        submatrix = matrix[i:i+step, :]
1028
1029        if submatrix.shape[0] < 128:
1030          zeros_array = np.zeros((128-submatrix.shape[0], 128))
1031          submatrix = np.vstack((submatrix, zeros_array))
1032
1033        if n_mat_channels == 3:
1034
1035          r = (submatrix // (256*256)) % 256
1036          g = (submatrix // 256) % 256
1037          b = submatrix % 256
1038
1039          rgb_image = np.stack((r, g, b), axis=-1).astype(np.uint8)
1040          img = Image.fromarray(rgb_image, 'RGB')
1041
1042        else:
1043          grayscale_image = submatrix.astype(np.uint8)
1044          img = Image.fromarray(grayscale_image, 'L')
1045
1046        if save_to_array:
1047          image_array.append(np.array(img))
1048
1049        else:
1050          img.save(output_folder + output_img_prefix + '_' + str(matrix.shape[1]) + '_' + str(i).zfill(7) + output_img_ext)
1051
1052    if verbose:
1053      print('Done!')
1054      print('=' * 70)
1055      print('Saved', (matrix.shape[0] // min(step, overlap))+1, 'imges!')
1056      print('=' * 70)
1057
1058    if save_to_array:
1059        return np.array(image_array).tolist()
1060
1061################################################################################
1062
1063def images_to_image_matrix(list_of_images,
1064                           num_img_channels=3
1065                           ):
1066
1067    if num_img_channels > 1:
1068      n_mat_channels = 3
1069
1070    else:
1071      n_mat_channels = 1
1072
1073    image_array = np.array(list_of_images)
1074
1075    original_matrix = []
1076
1077    for img in image_array:
1078
1079      if num_img_channels == 3:
1080
1081        rgb_array = np.array(img)
1082
1083        matrix = (rgb_array[..., 0].astype(np.int64) * 256*256 +
1084                  rgb_array[..., 1].astype(np.int64) * 256 +
1085                  rgb_array[..., 2].astype(np.int64))
1086
1087      else:
1088        matrix = np.array(img)
1089
1090      original_matrix.extend(matrix)
1091
1092    return original_matrix
1093
1094################################################################################
1095
1096def square_matrix_to_RGB_matrix(square_matrix):
1097
1098  smatrix = np.array(square_matrix)
1099  sq_matrix = smatrix[:smatrix.shape[1]]
1100
1101  r = (sq_matrix // (256 ** 2)) % 256
1102  g = (sq_matrix // 256) % 256
1103  b = sq_matrix % 256
1104
1105  rgb_array = np.stack((r, g, b), axis=-1)
1106
1107  return rgb_array.tolist()
1108
1109################################################################################
1110
1111def upsample_square_matrix(square_matrix, upsampling_factor=4):
1112
1113  smatrix = np.array(square_matrix)
1114  sq_matrix = smatrix[:smatrix.shape[1]]
1115
1116  scaling_array = np.ones((upsampling_factor, upsampling_factor))
1117  scaled_array = np.kron(sq_matrix, scaling_array)
1118  scaled_array = scaled_array.astype('int')
1119
1120  return scaled_array.tolist()
1121
1122################################################################################
1123
1124def downsample_square_matrix(square_matrix, downsampling_factor=4):
1125
1126  smatrix = np.array(square_matrix)
1127  sq_matrix = smatrix[:smatrix.shape[1]]
1128
1129  dmatrix = sq_matrix[::downsampling_factor, ::downsampling_factor]
1130  dmatrix = dmatrix.astype('int')
1131
1132  return dmatrix.tolist()
1133
1134################################################################################
1135
1136def plot_parsons_code(parsons_code, 
1137                      start_pitch=60, 
1138                      return_plot_dict=False, 
1139                      return_plot_string=False,
1140                      plot_size=(10, 10),
1141                      labels_size=16,
1142                      save_plot=''
1143                      ):
1144  
1145  '''
1146  Plot parsons code string
1147  '''
1148
1149  if parsons_code[0] != "*":
1150      return None
1151
1152  contour_dict = {}
1153  pitch = 0
1154  index = 0
1155
1156  maxp = 0
1157  minp = 0
1158
1159  contour_dict[(pitch, index)] = "*"
1160
1161  for point in parsons_code:
1162      if point == "R":
1163          index += 1
1164          contour_dict[(pitch, index)] = "-"
1165
1166          index += 1
1167          contour_dict[(pitch, index)] = "*"
1168          
1169      elif point == "U":
1170          index += 1
1171          pitch -= 1
1172          contour_dict[(pitch, index)] = "/"
1173
1174          index += 1
1175          pitch -= 1
1176          contour_dict[(pitch, index)] = "*"
1177
1178          if pitch < maxp:
1179              maxp = pitch
1180
1181      elif point == "D":
1182          index += 1
1183          pitch += 1
1184          contour_dict[(pitch, index)] = "\\"
1185
1186          index += 1
1187          pitch += 1
1188          contour_dict[(pitch, index)] = "*"
1189
1190          if pitch > minp:
1191              minp = pitch
1192
1193  if return_plot_dict:
1194    return contour_dict
1195  
1196  if return_plot_string:
1197
1198    plot_string = ''
1199
1200    for pitch in range(maxp, minp+1):

Showing the first 1,200 of 1522 lines. Download the file for the rest.