# Classifying peak and valley *regions* of a histogram

I've been playing with a few ways of classifying contiguous regions of a histogram as: 1) peak, 2) valley, or 3) in-between bit.

Global thresholding has worked minimally well for me so far, but I'm thinking that a better approach will be to classify peaks/valleys by a threshold of change, e.g. the derivative.

I've approximated the derivative at each point in the histogram from its neighboring points. Then I define extrema regions to be everything with a derivative less than some given threshold (e.g. the "flatish parts"). This seems to generally classify extrema (peaks+valleys), and points in-between, well for my application.

I run into a little trouble when further classifying the regions of extrema into peaks or valleys. Taking the 2nd order derivative is problematic when the data is jittery. The 2nd derivative test for concavity won't be consistent across a modestly jittery peak or valley.

Two questions follow from that:

1. Am I on a good path here, or is there some other approach to peak/valley classification I aught to consider before continuing on this path?
2. A solution to this problem seems to be a polyfit or smooth function on the data to generate a smoothly differentiable function, but in looking into this approach I note that ever higher order polynomial fits are increasingly likely to exhibit wavy behavior not unlike the original jitter in the data. So then, what is a good approach that would avoid this problem? E.g. how do I classify an entire extrema region as either peak or valley?
• After further thought I realize that a quadratic polynomial fit to each distinct region of points should yield a consistant 2nd derivative concavity test for that region. – David Parks Jun 25 '15 at 10:03
• Probably better to use a kernel density estimate for this purpose. See ksdensity. – A. Donda Jun 26 '15 at 13:30

After attempting quite a few approaches that didn't work too well including looking at derivatives, a modified edge detection algorithm, and a few others I tracked down this matlab function that does a way better job than I could manage rolling my own: imextendedmax.