简体   繁体   中英

Export .stl or .obj from 3D spectrogram using python

I am very new to python and programming in general. However, for an art project, I have spent the last week learning to program using python and found the plotly library. So amazing! It improved my code so much! I have written a code which lets me load in .wav files, creating a 3D spectrogram and exporting the 3D image to either a .png or html file. However, what I actually wanted to have is an .stl or .obj file of the 3D spectrogram (see image attached). I have already tried a few things, eg. I found a page which turns .png in .stl. It is a good alternative but it's not what I was looking for. I had another idea where I would make x .png slices of the 3D spectrogram and then build a .stl from the slices.

I was wondering, maybe someone of you has another idea or advice to export the 3D plot into a .stl/.obj file or even plot a 3D spectrogram and immediately export it to .stl or .obj.

Thank you very much in advance for your help =) Bests, Sweetheart90 3D spectrogram plot

Not that easy. You need to connect your vertices to a triangle mesh (shape n, 3, 3) Then you can use mk_stl_mesh to generate and export_stl_mesh to save:

def export_stl_mesh(*args, fileName:str, **kwargs):
    """
        exports geoms mesh as stl file
        call like:  im_ex_port.export_stl_mesh( np.flip(d.vtx[0][d.geoms[0].mesh], -1 ), 
                                    fileName=f"{g.name}_{str(g.gId)}")
    """
    content = mk_stl_mesh(*args, **kwargs)
    exportPath = os.path.join(sts.mediaPath, 'stls', f"{fileName}.stl")
    with open(exportPath, 'wb') as f:
        f.write(content.encode('ascii'))
    print(f"stl saved to exportPath: \n{exportPath}")

def mk_stl_mesh(mesh, *args, **kwargs):
    bounds = f"solid Exported from geometries.py" + '\n'
    content = bounds
    for triangle in mesh.reshape(-1, 3, 3):
        content += ('facet normal 0.000000 0.000000 1.000000' + '\n')
        content += ('outer loop' + '\n')
        for point in triangle:
            content += (f"vertex {' '.join([f'{t:6f}' for t in point])}" + '\n')
        content += ('endloop' + '\n')
        content += ('endfacet' + '\n')
    content += ('end' + bounds)
    return content

I forgot to mention a couple of important points to complete the answer:

  1. There are some variables in the functions like mediaPath which you must change to whatever you want.
  2. The most critical part is not obviously to create the mesh. There is a coding challenge 25 from "the coding train" that can help you there. It's JavaScript but the idea is the same.
  3. You should use numpy to do this. There is also a numpy.stl library which might have what you need.

Have fun

I have further tried things. I found the mtri function in matplob lib which should plot a 3D surface with triangles. so far so good. this is my code

import matplotlib.pyplot as plt
from scipy.io import wavfile
import numpy as np
from scipy import signal # spectrogram function
from matplotlib import cm # colour map
import matplotlib.tri as mtri


filename="/Users/sebastiankuhz/Desktop/kunst/Assemblypart1.wav"
samplingFrequency, signalData = wavfile.read(filename)

# basic config
sample_rate = samplingFrequency
sig_len_secs = signalData.shape[0]/samplingFrequency

# generate the signal
timestamps_secs = np.arange(sample_rate*sig_len_secs) / sample_rate
mysignal = signalData

# extract the spectrum
freq_bins, timestamps, spec = signal.spectrogram(mysignal,sample_rate)

z=10.0*np.log10(spec)

tri = mtri.Triangulation(freq_bins,timestamps)


# 3d plot
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(freq_bins[:, None], timestamps[None, :], z, cmap=cm.coolwarm)

plt.show()

Now, I receive the error: "ValueError: x and y must be equal-length 1D arrays".

Question: From a programming point of view, I understand the error, as the length of the arrays of the freq_bins and the timestamps are not the same. However in the plot I see that every timestamps value has "dedicated" freq_bins values and also z values. Thus, why do I then receive this error?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM