# Detecting trough widths and locations in 1d signal

I have the following function obtained from averaging 2d camera image over one axis, where detection of aligned objects is desired:

I need to detect (roughly speaking) locations and widths of the troughs -- sometimes and object will be missing, thus the trough will be much wider. The approach should have some resilience WRT possible lighting variations and other noise; this, and also a desire to use something new and useful) prevents me from going the naive way of thresholding and clustering or something similar.

I was looking at using wavelets: using ideal trough (Haar?) as the mother wavelet function, and the analysis would give its translation and scale at troughs in the signal.

I have no prior experience with wavelets. My background is numerics (variational analysis/FEM, particle systems programming), c++ and python, but I am quite new to signal processing (and its terminology).

What would be the most suitable thing to do? Suggestions, pointers to articles, books, or, best, code examples are much appreciated.

EDIT:

I finally used continuous wavelet transform (as implemented in scipy) where the result local maxima (in yellow) show both location (x-axis) and width (y-axis) of the trough.

import numpy as np
from scipy import signal
# scale the ricker (mexican hat) function to 10-60px width
widths=np.arange(10,60,.2)
cwtout=signal.cwt(vscan,signal.ricker,widths)
plt.imshow(cwtout,extent=[0,len(vscan),60,10],aspect='auto',vmax=abs(cwtout).max(),vmin=abs(cwtout).min())


I have a solution for your problem other than wavelet transforms that could be worth trying. Here are the steps :

1. Apply AGC & normalise the time series data. This will ensure that even in different lighting conditions etc and you will have relative similar peaks and troughs amplitudes.
2. Choose a wavelet that best represents your individual event. Eg : looks like inverted Haar could model your troughs well. Or cut a representative part of the normalised time series (your data). Say this is your reference wavelet W.
3. Correlate the reference Wavelet W with the data (time series). The values of correlation coefficients will give you a measure of spread of the troughs / peaks. The largest value will give the location.

Here is small code python code: if x is your time series data W is reference wavelet :

import numpy as np
corr_coeff= np.correlate(x,W,'same')

1. Though this will still require some thresholding and tests , normalisation should make it simpler.

A wavelet analysis or wavelet transform will give you scale(frequency) vs time vs amplitude. I am not sure how that will help you with your problem. Here is an algorithm for wavelet transform :

1. Choose your wavelet : Haar , Molet etc ..say $\psi (n)$
2. Choose Scale : the scale should be a multiple of smallest time interval dt.
3. Calculate the FFT of wavelet - $\Psi_0 (s\omega _k)$
4. Normalise FFT of the Wavelet - $\Psi (s\omega_k)=(2\pi s / \delta t)\Psi_0 (s\omega _k)$
5. Find FFT of time series x(t) = $X_k = 1/N \sum_{k=0}^{N-1} x(n) e^{-2\pi i k n/N }$
6. Then Wavelet transform is : $W(s)= \sum_{k=0}^{N-1} X_k\Psi^* (s\omega_k) e^ {i\omega_k n \delta t}$ ...where * is complex conjugate Generally the Fourier transform of the wavelet should be known analytically.

Few good sources :