How to use arrayfun to create an array whose value are relating to index?

4 views (last 30 days)
I'm now doing a project of image processing, but I have some troubles when using the function arrayfun(). Let me show the core part of my code first. I create an array named resizedImage.
resizedImage = zeros(dr, dc, 'uint8');
Then, I attempt to change the value of each entry of this array, so I use for-loop to achieve this.
for i = 1 : dr
for j = 1 : dc
resizedImage(i, j) = pixel_replication(img, i * dist_r, j * dist_c);
end
end
function val = pixel_replication(img, x, y)
% do something
end
However, for-loop is very time-consuming, so I try to use arrayfun() to make my code more efficient. Anyone can help me?
  3 Comments
Duen Chian
Duen Chian on 20 Sep 2023
Thanks for your reply. I've attached my code. Actually, my project is just an assignment and the requirement is to implement the function imresize().
dpb
dpb on 20 Sep 2023
for i = 1 : dr
for j = 1 : dc
resizedImage(i, j) = pixel_replication(img, i * dist_r, j * dist_c);
The order of the loops above is processing the array in row major, not column major order; rearranging those as
for j = 1 : dc
for i = 1 : dr
resizedImage(i, j) = pixel_replication(img, i * dist_r, j * dist_c);
could help some, but as @Dyuman Joshi notes, the time consumed will be in the function so whatever can be done there would be the place to look.

Sign in to comment.

Accepted Answer

Voss
Voss on 20 Sep 2023
Edited: Voss on 20 Sep 2023
function val = pixel_replication(img, x, y)
val = img(nearest(x), nearest(y));
end
function u = nearest(v)
l = floor(v);
r = ceil(v);
if v - l < r - v
u = l;
else
u = r;
end
end
nearest(v) returns the nearest integer to the input v, and if v is exactly halfway between the two nearest integers, then nearest(v) returns ceil(v). For a non-negative scalar number v, this is the same behavior as the built-in round function, but round also accepts array inputs, so if you use round instead of nearest, then you can easily vectorize your entire code:
function resizedImage = resizeImage_replication(originalImage, scalingFactor)
% load image
img = imread(originalImage);
% get number of rows and columns
[sr, sc] = size(img);
% adjust row and column
dr = ceil(sr * scalingFactor);
dc = ceil(sc * scalingFactor);
% % create an empty array - no longer necessary (and now resizedImage will
% % be the same class as originalImage, be it uint8 or whatever else)
% resizedImage = zeros(dr, dc, 'uint8');
% get dist
dist_r = (sr - 1) / (dr - 1);
dist_c = (sc - 1) / (dc - 1);
% pixel replication: resizedImage = imresize(img, scalingFactor, "nearest");
% for i = 1 : dr
% x = 1 + (i-1) * dist_r;
% for j = 1 : dc
% y = 1 + (j-1) * dist_c;
% resizedImage(i, j) = pixel_replication(img, x, y);
% end
% end
% vectors x and y:
x = 1 + (0:dr-1) * dist_r;
y = 1 + (0:dc-1) * dist_c;
% use round instead of nearest:
resizedImage = img(round(x),round(y));
end
  2 Comments
Duen Chian
Duen Chian on 21 Sep 2023
Thank you in advance! It work functionally and more efficiently now, but I still have a little question with the last line of your code. Why do two 1-D array result in a 2-D array? If x and y have the same size (e.g. 1 X 1300), won't they result in a 1-D array with the same size?
Voss
Voss on 21 Sep 2023
You're welcome!
The two 1-D arrays are indexing into the 2-D array img. round(x) is the row index and round(y) is the column index.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!