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

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 件のコメント

Dyuman Joshi
Dyuman Joshi 2023 年 9 月 20 日
arrayfun is not going to be faster than the for loop, at best it might match it.
Your best bet would be to see if the function pixel_replication() can be optimized.
Can you attach your code? Use the paperclip button to attach.
Duen Chian
Duen Chian 2023 年 9 月 20 日
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 2023 年 9 月 20 日
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.

サインインしてコメントする。

 採用された回答

Voss
Voss 2023 年 9 月 20 日
編集済み: Voss 2023 年 9 月 20 日
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 件のコメント

Duen Chian
Duen Chian 2023 年 9 月 21 日
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 2023 年 9 月 21 日
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.

サインインしてコメントする。

その他の回答 (0 件)

タグ

質問済み:

2023 年 9 月 20 日

コメント済み:

2023 年 9 月 21 日

Community Treasure Hunt

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

Start Hunting!

Translated by