2

Suppose I want do something similar to

image(1:end-1,2:end,:)

which here is taking part of colored image

but with unknown number of dimensions, i.e. which will work automatically like

image(1:end-1,2:end)

for 2 dimensions

image(1:end-1,2:end,:)

for 3 and

image(1:end-1,2:end,:,:)

for 4 and so on.

Suzan Cioc
  • 29,281
  • 63
  • 213
  • 385

4 Answers4

2

If you always want to take all of the 3rd dim and up, you can use

>> image(1:end-1,2:end,:,:,:)

even for 2D array.

Alternatively, you can use subsref for a less ad-hoc/hacky approach:

>> [S.subs{1:ndims(image)}] = deal(':');
>> S.subs{1} = '1:end-1';
>> S.subs{2} = '2:end';
>> S.type = '()';
>> subsref(image, S )
Shai
  • 111,146
  • 38
  • 238
  • 371
  • Shai offers a solution to a MATLAB problem that *doesn't* use `bsxfun`!? :) – Dang Khoa Jun 24 '13 at 02:42
  • @DangKhoa don't forget I have a background process that runs `bsxfun` in a loop (a vectorize loop) - so every solution of mine has `bsxfun` (and even that rhymes;) – Shai Jun 24 '13 at 04:58
0

I would have two ideas for this case.

1st way: You could reshape your image before, e.g.

% transform image to 3d format
% do not forget to transform all used entities to this 3d-format as well
sizeIm = size(image);
image3 = reshape(image,[sizeIm(1:2),prod(sizeIm(3:end)])

% work on image3
image3(1:end-1,2:end,:) = ...;

% transform back:
image = reshape(image3,sizeIm);

2nd way: Could be a solution to use eval and repmat, e.g.

eval(['image(1:end-1,2:end',repmat(',:',[1,length(size(image))-2]) ')'])

Depends a little bit on what you are using it for (setting, getting, ...).

matheburg
  • 2,097
  • 1
  • 19
  • 46
  • 1
    -1 For the eval. The code is already not simple to read, with `eval()` is gonna be a nightmare. – Oleg Jun 23 '13 at 19:46
  • 1
    Wow... that's "fair"! It is just one suggestion. Do you know where and how exactly he want's to use it? – matheburg Jun 23 '13 at 19:51
  • I down-vote `eval()` solutions in 99% of the cases (I will update in the future my description as to why). – Oleg Jun 23 '13 at 19:52
  • I know lots of arguments against `eval` on my own, nevertheless I gave 2 more or less useful answers which you don't have to upvote of course, but a warning comment with arguments against the 2nd way would have been more than enough. – matheburg Jun 23 '13 at 19:58
  • The reshape on the other hand is nice. – Oleg Jun 23 '13 at 20:07
0

Suppose you have an array A:

A  = rand(2,3,2,5,7);

Then, you can fill with ':', the remaining dimensions of your selection:

nd   = ndims(A);
subs = repmat({':'},1,nd-2);
A(1:end-1,2:end, subs{:})
Oleg
  • 10,406
  • 3
  • 29
  • 57
-1

I have there a little idea. You can formulate a function, that analyse the dimension of your Matrix with size(size(Matrix),2). Then you are able to construct a string, that contain your desired command with a little for loop and after this you execute this string with eval.

A=rand(3,3,3,3,3,3,3,3,3,3) %<--- change here dimension

dim=size(size(A),2)

addstr='';
if dim>2
    for i=1:dim-2
        addstr=[addstr ',:'];
    end
end

command=['A(1:2,1:2' addstr ')']

eval(command)