Hello. Suppose we have an 3D-array 4x4x4 with some values in it. The values are either 5 or 7.
A(:,:,1)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
A(:,:,2)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
A(:,:,3)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
A(:,:,4)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
How to refine this grid based on the majority rule? To make 2x2x2 grid, f.ex. Anew(1:1:1)= from 8 values of the blocks x1y1z1,x2y1z1,x1y2z1,x2y2z1,x1y1z2,x2y1z2,x1y2z2,x2y2z2 the values are 3 "5"s and 5 "7"th, so Anew(1:1:1)=7. If number of "5"s and "7"s is the same, choose "7".
The question is not easy, I think. Thank you!

 채택된 답변

Massimo Zanetti
Massimo Zanetti 2016년 10월 8일

4 개 추천

You may want to histogram the 3D array by 3D histogram. There many functions in Matlab central, just search for "N dimensional histogram".

댓글 수: 7

Vadim Tambovtsev
Vadim Tambovtsev 2016년 10월 8일
I googled an ancient 2003 year thread for N dimensional histogram, but didn't manage to apply their scripts to my case. https://se.mathworks.com/matlabcentral/newsreader/view_thread/56544
For 1D array it is easy to make such averaging, but 3D-array is more complex.
Massimo Zanetti
Massimo Zanetti 2016년 10월 8일
편집: Massimo Zanetti 2016년 10월 8일
Here I found a way to implement MAJORITY RULE in 3D array.
%array sizes
x=4; y=4; z=4;
%size of the block hxhxh
h=2;
%generate random 3d matrix of integers
A=randi(10,x,y,z)-1;
%initialize some useful indeces
ix=1:h:x; iy=1:h:y; iz=1:h:z;
[X,Y,Z]=meshgrid(ix,iy,iz);
D = reshape( 1:(x*y*z)/(h^3) , x/h , y/h , z/h );
H = 0:h-1;
%collect all the blocks in a cell
E = arrayfun( @(j) A(Y(j)+H,X(j)+H,Z(j)+H) , D , 'UniformOutput' , false );
%majority rule work as *mode* computed for each block
B = cell2mat( cellfun( @(block) mode(block(:)) , E , 'UniformOutput' , false ) )
To be more general, if you need blocks with size h1xh2xh3, this can be easily modified.
Vadim Tambovtsev
Vadim Tambovtsev 2016년 10월 8일
Your script is correct, but a have a comment. From the values in the "volume", it celects the most frequent value. However, if there are several values with the same frequency - it chooses the smallest.
Could you propose the modification, so that the program will choose a) the biggest value if the max frequencies are equal b) random value of these two values with the max frequeicies
Massimo Zanetti
Massimo Zanetti 2016년 10월 8일
편집: Massimo Zanetti 2016년 10월 8일
Ok, I found a trick by "overriding" the Matlab function mode, as in its call with only one output it only returns the smallest value. But other outputs have the information we want.
First, save in you current folder this function called myMode that overrides mode, and returns what we need (the biggest more frequent value):
function m=myMode(x)
[~,~,C]=mode(x);
%here you can play selecting what you want.
%to have biggest value (in this vector values are ordered ascending)
m=C{1}(end);
%to have some random value among the more frequent
%get a random element in C{1} (do it as an exercise)
end
Then in the other piece of code, just replace mode with myMode:
B = cell2mat( cellfun( @(block) myMode(block(:)) , E , 'UniformOutput' , false ) )
Vadim Tambovtsev
Vadim Tambovtsev 2016년 10월 8일
Thank you.
Vadim Tambovtsev
Vadim Tambovtsev 2016년 10월 8일
I haven't managed to get "random" values in myMode. Can you please tell me the answer?
m=C{1}( randi(numel(C{1})) );

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Jan
Jan 2016년 10월 8일

0 개 추천

If you realy have 2 values only, convert them to 0 and 1:
A(:,:,1)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
A(:,:,2)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
A(:,:,3)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
A(:,:,4)=[5 5 7 7; 7 5 7 7; 5 5 5 5; 7 7 7 7];
B = double(A == 7);
B = reshape(B, [2, 2, 2, 2, 2, 2]);
C = squeeze(sum(sum(sum(B, 1), 3), 5)) >= 4;
Result = 5 + C * 2;
% Or:
Result = repmat(5, [2,2,2]);
Result(C) = 7;
Andrei Bobrov
Andrei Bobrov 2016년 10월 8일

0 개 추천

B = mat2cell(A,[2,2],[2,2],[2,2]);
out = zeros(size(B));
for ii = 1:numel(out)
[a,~,c] = unique(B{ii}(:));
jj = accumarray(c,1);
k = sortrows([a,jj],[-2,-1]);
out(ii) = k(1);
end

카테고리

도움말 센터File Exchange에서 Data Type Conversion에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by