0

If I use this command in MATLAB, the image is distorted and is not retained. Why is this so?

>> b = imread('eight.tif');
>> b2 = imdivide(b,64);
>> bb2 = immultiply(b2,64);
>> imshow(bb2)
>> imshow(b);
Cœur
  • 37,241
  • 25
  • 195
  • 267
user75736
  • 131
  • 1
  • 4
  • I can't reproduce this, works fine over here (save for some obvious color changes)...Can you upload your figure somehow? – Rody Oldenhuis Jul 02 '13 at 05:58
  • what do you mean by "distorted"? – Shai Jul 02 '13 at 06:02
  • What if `b` is `uint8` array? I think that for all elements of `b` smaller that 64 corresponding `b2` elements will be zeros and so will be `bb2` elements due to integer arithmetics. – anandr Jul 02 '13 at 06:02

2 Answers2

3

You are performing operations on pixels of image stored as uint8 (unsigned 8-bits).
Dividing the pixels by 64 you basically shift-right the values by 6 (!) bits, that is, you leave only 2 (1) most significant bits per-pixel. Multiplying back by 64 fills the 6 least-significant-bits with zeros - data is lost.


Here's a little example:

>> a = uint8(153); dec2bin(a)
ans =
 0b10011001
>> b = a/64;       dec2bin(b)
ans =
 0b00000010

Note how all the 6 bits on the right ( 011001 ) are GONE! only the two bits from the left (10) are remained (shifted to the right). This division operation caused you loss of data.
Now, multiplying back:

>> c = b*64;       dec2bin(c)
ans =
 0b10000000

All the 6 bits on the right are now 0! the previous values 011001 are GONE!


Another exampe by Rody:

data = uint8(1:255);

figure(1), clf, hold on

plot(data, data, 'b')
plot(data, data/uint8(64)*uint8(64), 'r')

xlabel('Original Values')
ylabel('Ouptut values')

axis tight
legend('Original color space', 'Color space after integer division/multiply',...
    'Location', 'NorthWest')

enter image description here

Community
  • 1
  • 1
Shai
  • 111,146
  • 38
  • 238
  • 371
2

This is because you dividing a uint8 image. When you divide your image (which has a range of values between 0 and 255) by 64 you will end up with an image with values 0, 1, 2, 3 and 4. When you multiply it back, you will get 0, 64, 128, 192, and 255, instead of the full range of values you initially had.

Check this out: imshow(b/64*64). THis will show you the same artifact.

Now check this: imshow(uint8(double(b)/64*64)). This will show you the original image. You are able to recover the values in this case because the operations are performed on doubles rather than uint8.

Diana
  • 1,301
  • 1
  • 9
  • 21
  • Btw, you can use `unique(b(:))`. This will list all the unique values in the `b` matrix, and it can help you inspect what changed. – Diana Jul 02 '13 at 06:18