Currently I am doing a research internship at Limbic (paid for in part by MITACS). While the details of this research are TOP SECRET! I can reveal that the nature of the work involves creating audio signal processing algorithms and, while may come as a surprise, I use Python for this development.
PYTHON!? (you might be thinking)
But it's an interpreted language and is therefore inherently slow. Why would you ever use it for audio signals?
Well, the answer is fairly simple: NumPy
NumPy is a module for Python which takes advantage of Python's ability to interact with compiled C code (see: CTypes or SWIG for more on this) to suppot multi-dimensional arrays. NumPy also gives a host of methods for operating on these arrays (e.g. dot product, cross product, FFT!). Essentially, C-array data structures with a backend (and high level Python interface) to operate on these arrays.
A bunch of other Python modules can take advantage of this speed: PILLOW, SciPy, and Matplotlib (just for example).
(SciPy is especially sweet because it adds Matlab™ like functionality BUT with some serious speed thanks to the C back end).
I should point out that I do not use Python for Real-Time signal processing but instead take advantage of the Python-NumPy combo to quickly prototype different processes and analyze the outcome. While writing processes in C/C++ is still basically a necessity for Real-Time operations, analysis of signals is annoying. In the end, after I know things are going to work (because Python showed me it will) I can then take the steps port the process into a compiled language.
TLDR; NumPy extends Python with C arrays making it a great tool for research and experimentation.
Here's a an example of an image filter (threshold) using NumPy and PILLOW (and a bit of Matplotlib)
Importing the necessary modules:
import numpy as np from PIL import Image #PILLOW for loading images import matplotlib.pyplot as plt
Load the image:
img = Image.open('me.jpg')
Here's the image i've loaded:
Convert PIL datatype to NumPy array:
img_array = np.asarray(img)
This is an easy conversion and allows to manipulate the image as a C-type array.
Plot a histogram of the image:
width = img_array.shape height = img_array.shape pix = img_array.shape #number of pixels # graph the histogram (256 bins for the 256 different values) hist_array = np.reshape(img_array, width * height * pix) #this makes the image 1d array. # hist_array = hist_array.flatten() #alterntive method plt.hist(hist_array, bins=256, normed=1) plt.show() #plt.savefig('hist.png') #you can also save the graph
The histogram can be useful for finding where the energy in the image is. For example it might be useful to keep only the pixels with values between
0 and 25 and values between
180 and 200.
I'm not using this for this example but it's nice to see how easy analysis can be.
Get some other info:
#stats mean = np.mean(img_array) std = np.std(img_array)
These are some useful stats about the image.
Make a mask and use it to filter the image:
#find all the values above the mean mask = np.greater(img_array, mean+std) #apply the mask filtered_array = np.multiply(img_array, mask)
mask variable is an array with the same shape as
img_array but values greater than the
mean + standard deviation set to
So, when the
img_array is multiplied by the
mask, the resulting array is filtered since all values less than
mean + std are set to 0.
Output the image:
#convert output image back to Image type for export out_img = Image.fromarray(filtered_array) out_img.save('filtered_image.jpg')
It's easier to save the image as as a regular file using PILLOW, so we convert the NumPy array back into an Image (how convenient that PILLOW has a
Here's the result:
Anyone who uses Photoshop will recognize this as the