Skip to content

Instantly share code, notes, and snippets.

@pepijndevos
Created May 14, 2024 20:38
Show Gist options
  • Save pepijndevos/fea517371a543e55fa8f15518b64242e to your computer and use it in GitHub Desktop.
Save pepijndevos/fea517371a543e55fa8f15518b64242e to your computer and use it in GitHub Desktop.
image to sound
from PIL import Image
from PIL import ImageFilter
import numpy as np
import matplotlib.pyplot as plt
from scipy.io.wavfile import write
threshold = 200
# Open image and convert to numpy array
img = Image.open("matterhorn.png")
# Apply Gaussian blur
# img = img.filter(ImageFilter.GaussianBlur(radius=1))
a = np.array(img)
mask = np.linalg.norm(a-a[0,0], ord=2, axis=2)
mask = np.where(mask>threshold, 255.0, 0.0)
mask = mask.cumsum(axis=0)
mask = mask.clip(0.0, 255.0)
# Convert numpy array back to image
new_img = Image.fromarray(mask)
# Save the new image
new_img.save("mask.gif")
window_size = 1000
sample_rate = 48000
contour = np.argmax(mask, axis=0)
contour = (-contour + np.max(contour))
contour = 10**(contour.astype(np.float64)/20)
angle = np.exp(1j * 2 * np.pi * np.random.rand(len(contour)))
peak = np.argmax(contour)
contour = angle * contour
steps = range(len(contour)-window_size+1)
for i in steps:
step_peak = peak - i
if step_peak < 0:
break
# print(step_peak)
freq_bin = step_peak / (window_size * 2 + 1) * sample_rate
# print(freq_bin)
window = contour[i:i+window_size]
window = np.hstack((0, window, window[::-1]))
wave = np.real(np.fft.ifft(window))
wave /= np.max(np.abs(wave))
# wave = np.tile(wave, 10)
write(f'sample/wave{int(freq_bin):05d}.wav', sample_rate, wave)
# bounds = (i, 0, i+window_size, img.height)
# win = img.crop(bounds)
# win.save(f'img/win{int(freq_bin)}.png')
# mwin = new_img.crop(bounds)
# mwin.save(f'mask/mwin{int(freq_bin)}.gif')
# plt.plot(sound)
# plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment