Why a matrix multiply a variable and then be divided by the same variable produce different results?

1 次查看(过去 30 天)
clear all;
matFilename='./test.tif';
b=mean(mean(imread(matFilename)));
matData1=imread(matFilename)*(b/b); %%line 4
matData2 = imread(matFilename)*b/b; %%line 5
figure;
subplot(1,2,1)
imshow(matData1,[]);
subplot(1,2,2)
imshow(matData2,[]);
Hello, I am confused by the code show above, b is just a number, so why the matrix multiply b and then divide the same b (line 5) would not be the same as the matrix itself (line 4), as the image showed?
The sample image file is attached on the .zip file.
Thanks!

采纳的回答

Stephen23
Stephen23 2020-10-26
编辑:Stephen23 2020-10-26
"I am confused by the code show above, b is just a number, so why the matrix multiply b and then divide the same b (line 5) would not be the same as the matrix itself (line 4), as the image showed?"
You have not taken into account operator precedence:
and the behavior of numeric operations on integer data (by which I mean arrays with integer data class, not just whole numbers). These two operations are NOT the same when x has an integer data type (for sake of this argument we assume b is a scalar double):
x*(b/b) % line 4
x*b/b % line 5
Because of operator precedence, "line 4" is equivalent to:
x*(1)
x
but "line 5" is equivalent to
(x*b)/b
which is not the same thing at all because with integer data classes those operations are not associative (we cannot just arbitrarily change the order of the operations, unlike the maths you learned in school) and can over/underflow and lose information. Which for your image data, they certainly do!
For example what happens if we multiply uint8(255) by 1000? Do we get expect to get 255000? No, we do not, because uint8 only supports values from 0 to 255 and the documentation tells us that operations returning a value outside its range simply saturates to its highest value, so we expect the output to be 255. Ditto for underflow.
Lets try it:
>> x = uint8([0,127,255])
x =
0 127 255
>> b = 1000;
>> x*b % all non-zero values saturate to 255!
ans =
0 255 255
>> x*b/b % line 4, all values saturate to 0!
ans =
0 0 0
And for comparison:
>> x*(b/b) % line 5, equivalent to x/1 == x
ans =
0 127 255
If you want to perform those operations in an "arbitrary" order then you will either need to consider the data class very carefully, or simply convert to a floating-point class beforehand**, e.g.:
im = im2double(imread(matFilename)); % convert to floating-point!
b = mean(mean(im));
matData1 = im*(b/b);
matData2 = im*b/b;
** strictly speaking also not completely associative, but close enough in most cases.

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Numeric Types 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by