Why does my speedup resolution reduction code not function correctly?

2 views (last 30 days)
Dear community,
For a project I have written a code that can reduce the resolution without making use of the standard codes in Matlab. I have tested the code that i have written and it works perfectly. the only disadvantage is that it takes quite some time to run. so i have simplified the code and has reduced the time from 1 minute to 3 seconds. But it does not give the correct image, the only differece is that in the code that works i use a vector to store the values in the pixel and use the sum funcion to add them together at the end. In the second I add the value of the pixels together during the loop the codes i have shown below. I am wondering why my second code does not give the same result as the previous code, I can not find the error. p.s. I have added pictures so the difference is clear.
%% Code that functions correctly but is slow:
clc; clear all; close all;
A = imread('einstein.jpg');
image(A)
resred = 5; % 5*5 pixels will become 1 pixel
X = floor(size(A,2)/resred);
Y = floor(size(A,1)/resred);
B = zeros(Y,X,3);
for rgb = 1:3
for i = 1:Y
for j = 1:X
p = 1;
clear s;
for ai = (resred*i-(resred-1)):(resred*i)
for aj = (resred*j-(resred-1)):(resred*j)
s(p) = A(ai,aj,rgb); % store the values in a vector
p = p+1;
end
end
B(i,j,rgb)=round((sum(s))/(resred^2));
end
end
end
B2=uint8(B);
image(B2);
%% Code that does not function correcly
clc; clear all; close all
A = imread('einstein.jpg');
image(A)
resred = 5; % 5*5 pixels will become 1 pixel
X = floor(size(A,2)/resred);
Y = floor(size(A,1)/resred);
B = zeros(Y,X,3);
for rgb = 1:3
for i = 1:Y
for j = 1:X
s=0;
for ai = (resred*i-(resred-1)):(resred*i)
for aj = (resred*j-(resred-1)):(resred*j)
s = s + A(ai,aj,rgb); % add the next value to the previous values
end
end
B(i,j,rgb)=s;
end
end
end
B=uint8(round(B/resred^2));
image(B)

Answers (1)

Kautuk Raj
Kautuk Raj on 19 Feb 2024
It is my understanding that you would like to determine why two versions of your MATLAB code, which aim to reduce image resolution, produce different results despite their apparent similarity, with the first being slower but correct, and the second being faster but incorrect.
The discrepancy between the two versions of your code is since you are not handling the data type correctly during the summation in the second code snippet. In MATLAB, images are stored as uint8 data type, which can hold integer values from 0 to 255. When you add uint8 numbers together, the result will also be of type uint8 and will wrap around if it exceeds 255, which is not the behavior you want when averaging pixel values.
To fix this, you should convert the pixel values to a data type that can handle larger intermediate values, such as double, before performing the summation. After the averaging, you can then convert the result back to uint8.
This is the updated code snippet with the modifications:
clc; clear all; close all;
A = imread('einstein.jpg');
image(A);
resred = 5; % 5*5 pixels will become 1 pixel
X = floor(size(A,2)/resred);
Y = floor(size(A,1)/resred);
B = zeros(Y,X,3); % Initialize B as a double to handle larger intermediate values
for rgb = 1:3
for i = 1:Y
for j = 1:X
s = 0; % Initialize s as a double
for ai = (resred*i-(resred-1)):(resred*i)
for aj = (resred*j-(resred-1)):(resred*j)
s = s + double(A(ai,aj,rgb)); % Convert to double before summing
end
end
B(i,j,rgb) = s; % Keep B as a double until after the division
end
end
end
% After the summation and averaging, convert B back to uint8
B = uint8(round(B / resred^2));
image(B);
After making these changes, this code will produce the same result as the original one but with improved performance.

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!