Essentially im looking for a reliable version of this puzzler, but that searches for largest group of values rather than equal values : http://blogs.mathworks.com/videos/2008/08/18/puzzler-find-largest-connected-island/?s_tid=srchtitle that I can adjust to pick out the 10% region
find contiguous region with highest values
12 views (last 30 days)
Show older comments
I'm trying to get the indexes of the region covering 10% of an m x n graph that has the highest values.
For example:
0 0 0 0 0 3
2 2 2 0 0 0
0 0 0 0 0 1
0 0 0 0 1 2
0 0 0 0 0 0
Should give me rows 2,2,2 and columns 1,2,3 (the output format doesn't matter for my purposes).
The region needs to be contiguous, and not just the region with the single highest value. Could someone point me in the right direction?
4 Comments
Walter Roberson
on 23 Oct 2016
This does not answer to the question of what happens for a tie, and does not answer to the question of how you determine which cluster has the "highest values" across clusters of different sizes and where simple maximum is not the key. Is the key the mean over the cluster? Is the key the sum over the cluster?
Answers (3)
Chaya N
on 21 Oct 2016
Edited: Chaya N
on 21 Oct 2016
There may be a nice (but slightly complicated) way of getting the linear indices here. The idea is something like this: Get connected components ( blobs shall we say?) --> Get pixel index list --> For each set of pixels, compute their pixel sum --> Find the index of the maximum pixelsum --> Get linear indices for the blob with the maximum pixelsum.
The code would be something like this:
x = [0 0 0 0 0 3 % your example here
2 2 2 0 0 0
0 0 0 0 0 1
0 0 0 0 1 2
0 0 0 0 0 0];
CC = bwconncomp(x); % Blobs and their data
SumPixels = cell2mat(cellfun(@(y) sum(x(y)),CC.PixelIdxList,'UniformOutput',0)); % Get Pixelsum
[~,idx] = max(SumPixels);
LinIdx = CC.PixelIdxList{idx};
And Voila! I get:
LinIdx =
2
7
12
You could find the row and column indices from the above, but this is where I leave you.
PS: For pedagogical reasons, I suggest you look up the bwconncomp and cellfun functions. To learn more about linear indices, please look at the "More About" section here .
2 Comments
Chaya N
on 22 Oct 2016
Edited: Chaya N
on 22 Oct 2016
It would depend on how you separate your regions of interest. How do you define that certain pixels or a certain contiguous region belongs to your object of interest and not the background?
Also, you could always adapt/modify your non-integer-valued array long enough to get your program running. You could even change all your background values to zeros with a logical statement. My point is, the entire logic of the code depends on where the 'edges' of your regions lie, and a handful of pixels more or less makes a big difference to the region that you would obtain.
Image Analyst
on 22 Oct 2016
Try ismember() and you can do it in 2 lines. See this well commented demo:
% Define sample data consisting of integers
% (Slightly different than your example)
m = [0 0 0 0 0 3
2 2 2 0 0 0
0 0 0 0 0 1
0 3 3 0 1 2
0 0 0 0 0 0]
% 3 is the "highest value" and is what is sought.
% 3 occurs in two regions (places).
% Find those two regions of highest value
% and put locations into a logical array.
locations = ismember(m, max(m(:)))
% Get a new matrix withteh actual values.
highestValueRegions = m .* locations
0 Comments
Image Analyst
on 22 Oct 2016
If you have floating point values, I think what you're trying to say is that you want a matrix with only elements that are in the highest 10% of all values in the array. You can do this like:
% Define sample data consisting of floating point numbers
m = 100 * rand(6, 5)
% Sort the array
sortedm = sort(m(:), 'descend')
% Find the 10% index
index10 = ceil(0.1 * numel(m))
% Determine the value that 10% of the values lie above
value10 = sortedm(index10)
% Get binary "map" of where these highest 10% of values live:
binaryImage = m >= value10
% Extract a matrix with only the highest 10% of floating point values:
output = m .* binaryImage
When I ran it, this is what I got. Tell me if this is what you were thinking of:
m =
9.1113 64.762 23.623 77.029 25.644
57.621 67.902 11.94 35.022 61.346
68.336 63.579 60.73 66.201 58.225
54.659 94.517 45.014 41.616 54.074
42.573 20.893 45.873 84.193 86.994
64.444 70.928 66.194 83.292 26.478
sortedm =
94.517
86.994
84.193
83.292
77.029
70.928
68.336
67.902
66.201
66.194
64.762
64.444
63.579
61.346
60.73
58.225
57.621
54.659
54.074
45.873
45.014
42.573
41.616
35.022
26.478
25.644
23.623
20.893
11.94
9.1113
index10 =
3
value10 =
84.193
binaryImage =
6×5 logical array
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 1 1
0 0 0 0 0
output =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 94.517 0 0 0
0 0 0 84.193 86.994
0 0 0 0 0
13 Comments
Chaya N
on 22 Oct 2016
Edited: Chaya N
on 22 Oct 2016
To add to the above, I would suggest a square mask (or scrolling array, if you'd like) with odd number of elements so you would have something of a 'center' value. This is a common tactic used in filtering operations. Also, the mask size and shape would influence the data, so choose as small a square size as possible so you would not end up manipulating your data over the necessary amount. In my example, I have chosen a 3x3 mask because it is the smallest odd square that I could use that is greater than k.
Image Analyst
on 22 Oct 2016
To get the mean of the interactions (pixels) in a horizontal 1-by-2 sliding window, do this:
[rows, columns] = size(im)
for col = 1 : columns
windowWidth = col;
kernel = ones(1, windowWidth) / windowWidth;
meanImage = conv2(im, kernel, 'same');
% Now do something with meanImage.....
end
where m is your interaction matrix.
To do the same but in a vertical 2-by-1 sliding window, do this:
[rows, columns] = size(im)
for row = 1 : rows
windowHeight = row;
kernel = ones(windowHeight, 1) / windowHeight;
meanImage = conv2(im, kernel, 'same');
% Now do something with meanImage.....
end
If you want, you could use a double for loop over both rows and columns to create all possible kernel shapes:
[rows, columns] = size(im)
for col = 1 : columns
for row = 1 : rows
kernel = ones(row, col)/(row * col);
meanImage = conv2(im, kernel, 'same');
% Now do something with meanImage.....
end
end
Not sure what you want to do with the mean image once you have it though.
See Also
Categories
Find more on Matrix Indexing 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!