Finding local minima and its indices in a 2D matrix.

27 views (last 30 days)
Hi, I have a set of data which oscillates between minimums and maximum values. The min and max values change over time. I want to see the minima that has occured before the global max in the array.
In order to do that, i start at the global max(i,j) and look backwards checking for a minima. A minima is when the condition is a[i,j] < a[i,j-1] & a[i,j] < a[i,j+1] is satisfied.
Tried to write a loop for this but it iterates only once. Any inputs? Thanks. for f=1:18 C=B; count=0; while ( C(f,o(f))> C(f,o(f)-1)) o(f)=o(f)-1; count= count+1; end; if( C(f,o(f))< C(f,o(f)+1)) display(o(f)); display(C(f,o(f))); end; % break; display(count); end;

Answers (3)

Stephen23
Stephen23 on 27 Jan 2015
Edited: Stephen23 on 28 Jan 2015
You need to locate the minima and exclude any after the global maximum value. Doing this using looping is not an optimal solution in MATLAB, here is a robust vectorized alternative:
>> A = [3,3,5,3,2,2,4,3,2,1,2,3,6,4,0,1]; % fake data vector.
>> [~,idx] = max(A);
>> idy = diff(sign(diff(A)))>0;
>> idz = diff(A(1:2));
>> idy = [idz>0 || idz==0&&idy(1), idy];
>> idy(idx:end) = false;
>> find(idy)
ans = [ 1 2 5 6 10]
>> A(idy)
ans = [ 3 3 2 2 1]
Note that this code locates all local minima, even if they are doubled (e.g. 3,3 and 2,2), and also identifies leading minima (e.g. 3,3). The indices of these minima are shown with find(idy), while the minima values are shown with A(idy). Note that these exclude the minimum 0 which occurs after the global peak of 6.
If your data never has doubled minima, then you can simplify the code a little bit:
>> A = [1,5,3,2,4,3,2,1,2,3,6,4,0,1];
>> idy = [diff(A)>0,true] & [true,diff(A)<0];
>> [~,idx] = max(A);
>> idy(idx:end) = false;
>> find(idy)
ans = [ 1 4 8]
>> A(idy)
ans = [ 1 2 1]
  2 Comments
Vittal Rao
Vittal Rao on 27 Jan 2015
Edited: Vittal Rao on 27 Jan 2015
Thanks for answering. I do see this method gives the index and the value of the minima as the last element fot the answer vector. In above case 8 and 1.
I am going to try and expand this to multi dimensional array. Should that work? I have 18 rows to analyze.
i think i should modify
>> idy = [idz>0 || idz==0&&idy(1), idy];
as >> idy = [idz>0 || idz==0&&idy(i), idy];
where i denotes loop. But i cannot understand how the above statement works.
Stephen23
Stephen23 on 28 Jan 2015
Edited: Stephen23 on 28 Jan 2015
Do not use i or j as the names of your variables, as these are the names of the inbuilt imaginary unit .
Can you please clarify your problem: in your original question you state that you want "the minima that has occured before the global max", where "minima" in english is the plural of minimum. However in your comment above you seem to only refer to the single minimum before the global maximum "In above case 8 and 1". Which do you require: the single minimum before the global maximum, or all minima before the global maximum?
I am happy to help you with solving this, and knowing this information makes a big difference to the code we need to write to solve it!

Sign in to comment.


Image Analyst
Image Analyst on 27 Jan 2015
If you have the Image Processing Toolbox, you can use the function imregionalmin(). From the help:
Syntax
BW = imregionalmin(I)
BW = imregionalmin(I,conn)
Description
BW = imregionalmin(I) computes the regional minima of I. The output binary image BW has value 1 corresponding to the pixels of I that belong to regional minima and 0 otherwise. BW is the same size as I.
Regional minima are connected components of pixels with a constant intensity value, and whose external boundary pixels all have a higher value.
By default, imregionalmin uses 8-connected neighborhoods for 2-D images and 26-connected neighborhoods for 3-D images. For higher dimensions, imregionalmin uses conndef(ndims(I),'maximal').
BW = imregionalmin(I,conn) specifies the desired connectivity. conn can have any of the following scalar values.
  1 Comment
Image Analyst
Image Analyst on 27 Jan 2015
Try this:
A = [3,3,5,3,2,2,4,3,2,1,2,3,6,4,0,1] % fake data vector.
localMins = imregionalmin(A)
In the command window:
A =
3 3 5 3 2 2 4 3 2 1 2 3 6 4 0 1
localMins =
1 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0
You see everywhere that A is a local min, the localMins array is 1. And where it is on the side or a maximum, localMins will be 0.
Does that help?

Sign in to comment.


Yongkai liu
Yongkai liu on 5 Jan 2019
what's inside the imregionalmin?
  1 Comment
Image Analyst
Image Analyst on 5 Jan 2019
It's an m-file that you can edit to see what's inside:
>> edit imregionalmin
essentially it inverts the image and calls imregionalmax().

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!