Wrong answer being given when adding whole numbers

5 次查看(过去 30 天)
I am currently working on a problem in which I apply a 3x3 smoothing filter to an image. However, the actual error I have is in a simple mathematical error where Matlab is outputing a wrong answer for a simple addition. When adding 156 and 159, the result it gives is 255, not 314. Below is my code and the output showing this happening.
% This image comes with Matlab, should be universally available
image=imread('cameraman.tif');
imshow(image);
figure
imshow(filter3x3(image));
% Apply 3x3 smoothing filter to image
function image = filter3x3(image)
% Find height and width of image
imageSize = size(image);
H = imageSize(1);
W = imageSize(2);
% Save copy of image
imageOriginal = image;
% Iterate through every pixel except the outmost ones
for i = 2:H-1
for j = 2:W-1
sum = 0;
% For the eight pixels dirrectly adjacent to pixel and the
% pixel itself
for x = -1:1
for y = -1:1
% Fetch pixel and save it to a sum
pixel = imageOriginal(i + x, j + y);
fprintf("Pixel value: %d\n", pixel);
fprintf("Sum before new pixel: %d\n", sum);
sum = pixel + sum; % <----------------------------------- Error happens at this equation
fprintf("Sum with new pixel: %d\n", sum);
end
end
% Find the result of the filter for the pixel
filterResult = round(sum/9.0);
% Apply result to pixel
image(i,j) = filterResult;
end
end
end
Output for first two pixels:
Pixel value: 156
Sum before new pixel: 0
Sum with new pixel: 156
Pixel value: 159
Sum before new pixel: 156
Sum with new pixel: 255
The answer for this opperation is clearly wrong, and for the life of me I can not understand why such a simple operation I literally can do in my head is off by almost 19% of the correct answer. Why is this happening, and is there a way to get the correct answer?
  2 个评论
Matthew Wilcox
Matthew Wilcox 2021-11-22
After looking through the code one more time, I noticed that for some reason some odd reason, when adding the uint8 value 156 to the double 0, the result is a uint8 value 156. Then, when trying to add the uint8 value 159 to the sum's value, which is the uint8 value 156, the result can not be any larger than 255 based on the size limitations for the uint8 data type. However, I always thought Matlab's policy during an addition was to take the larger data type to prevent loss. Is that not how Matlab handles types? If so what is the method it uses to decide which data type to keep in situations like this? I program with Matlab a lot for my classes, and I feel like this is something I'll need to know.
My origional question is answered, I can just force the type to remove the issue. But why this is happening is still a mystery for me, hence why I'm not closing the question.
Stephen23
Stephen23 2021-11-25
The documentation here:
explains various operations on intger classes, including this section:
"Arithmetic Operations on Integer Classes"
"MATLAB can perform integer arithmetic on the following types of data:"
  • "Integers or integer arrays of the same integer data type. This yields a result that has the same data type as the operands..."
  • "Integers or integer arrays and scalar double-precision floating-point numbers. This yields a result that has the same data type as the integer operands..."
and procedes to give examples. This explains exactly the behavior that you observe. This has always been the behavior of MATLAB arithmetic operations involving integer types (and is occasionally discussed on this forum).
The source which told you that integer types are enlarged/expanded to prevent loss is incorrect.

请先登录,再进行评论。

采纳的回答

David Goodmanson
David Goodmanson 2021-11-22
编辑:David Goodmanson 2021-11-22
Hello Matthew,
this is happening because the image uses uint8 values (unsigned integer 8 bit), with a range of 0 to 2^8 -1 = 255. So the addition overflows to 255. Depending on what you want to do, you could go with image1 = double(image) . Once both the values to be added are in double precision, the sum works. Double precision has 8 times the memory requirement, which hardly matters in this case unless there are a lot of images. Another possiblilty might be uint16(image), 0 to 2^16 -1 = 65535.
  2 个评论
Matthew Wilcox
Matthew Wilcox 2021-11-22
I managed to figure that out not too long ago, but why is the variable sum, which is a double when I create it, turn into a uint8 when I add a uint8 to it? How does Matlab handle typing in these kinds of situations? I always though it kept the larger data type to avoid data loss, but that clearly isn't the case, at least not always.
David Goodmanson
David Goodmanson 2021-11-22
Hi Matthew
a quick nonexhaustive review shows that integers of different classes can't be combined, integer of a certain class + double stays in that class, and integer of a certain class + large double overflows to the max value for that class.

请先登录,再进行评论。

更多回答(0 个)

Community Treasure Hunt

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

Start Hunting!

Translated by