Obtain the peak value of one-dimensional data (C++/Matlab)

This method is derived from solving the problem of the distance between the peaks of a certain column (one-dimensional discrete data) in the image power spectrum. For example, the distribution of the input one-dimensional discrete data is as follows:

 

That is, from left to right, they respectively represent the numerical value of the subscript from 1 to n (0 to n-1 in c/python), the interval is 1, and n represents the length of one bit of data. Redefine the peak of the data here: satisfy the equivalent interval of both left and right values ​​smaller than it , such as [2,2] of [1,2,2,1] and [2] of [1,2,0]. It is the "peak" of the data, but there is no peak in [1,2,2,4] and [1,2,2,2]. The highest peak among all peaks is called the "main peak", and the others are called "secondary peaks". For the above example, all peaks have been manually circled.

As shown in the figure, there are 18 peaks in total. Now the question is, how do you get the values ​​(or coordinates) of all the peaks when you input a set of data? (The coordinates use the midpoint to indicate the interval)

Taking the coordinates as an example, the coordinates of each peak are represented by the midpoint of the interval in which it is located.

First define two variables here: start_peak and end_peak. Dynamically indicate the start and end coordinates of each peak interval.

Traverse one-dimensional data. If the value of the current data is greater than the value of the previous (left) data, it means that it is in the ascending process. Update start_peak to the subscript of the current value; if it is less than, (and the value of start_peak is not the initial value) , it means that The subscript of a data is already the end coordinate of the interval of the peak, update end_peak to the subscript of the previous value, so that the start and end coordinates of the peak are obtained, so after the update, the average of start_peak and end_peak The value is saved in the result, and start_peak is attributed to the initial value (to prevent saving a peak each time during the descending process, which echoes the boldface of the previous paragraph). At the end of the traversal, return. Other peak or interval equivalence can be obtained with slight modification.

Matlab version code:

function peak_index=find_peak(data)
    n=length(data);%数据长度
    start_peak=0;%初始化
    end_peak=0;
    t=0;
    for i=1:n
        if (i>=2 && data(i)>data(i-1))
            start_peak=i;
        end
        if (i>=2 && data(i)<data(i-1)&&start_peak)
            end_peak=i-1;
            t=t+1;
            peak_index(t)=(start_peak+end_peak)/2;
            start_peak=0;     %初始化  
        end
    end
end

C++ version: (never run, pure direct translation)

    vector<int> find_peak(vector<int>& data) {
        vector<int> ans;
        int n=data.size();
        int start_peak=-1;
        int end_peak=-1;
        for(int i=0;i<n;i++){
            if(i>=1 && data[i]>data[i-1])
                start_peak=i;
            if(i>=1 && data[i]<data[i-1]&& start_peak>=0){
                end_peak=i-1;
                ans.push_back(ceil((end_peak+start_peak)/2));
                start_peak=-1;
            }
        }
    return ans; 
    }

The final return result:

After comparison, it is consistent with the picture.

Guess you like

Origin blog.csdn.net/qq_36614557/article/details/109657803