필터 지우기
필터 지우기

how to convert a monochrome image of depth 24 bits into a monochrome image of depth 8 bits ?

조회 수: 5 (최근 30일)
this is to convert a monochrome image of depth 24 bits into a monochrome image of depth 8 bits ?

답변 (2개)

Image Analyst
Image Analyst 2013년 8월 24일
There's no 24 bit integer in MATLAB, so try this:
clc;
x=int32(123423534) % Whatever....
% Find out what is the max value for x.
maxX = intmax(class(x))
% Normalize
x_uint8 = uint8(double(x) * 255 / maxX)
  댓글 수: 1
DGM
DGM 2024년 6월 6일
편집: DGM 2024년 6월 6일
There are problems with this.
The simplest is that the output of intmax() is determined by the requested class. As a consequence, you'll get an error because of the mixed int/float class arithmetic.
The next problem is that we don't actually want intmax() of the container class. We want to know the range of a uint24 number, since that's the scale of the stored data. After all, the only reason our data isn't full-scale is because we don't have a native 24b integer class to store it in. If we're moving to a standard numeric class, we don't need to stay mis-scaled.
While int32 is wide enough to hold uint24 data, we don't really have a good reason to be storing unsigned data in a signed container and inviting confusion. If our reason for using a signed integer container is that our underlying data is also signed, then the rescaling operation won't accomodate the conversion. That said, how many people actually are using int24-scale images? I don't know, but it's probably not many.

댓글을 달려면 로그인하십시오.


DGM
DGM 2024년 6월 6일
편집: DGM 2024년 7월 6일 1:11
Here's a more comprehensive example which should handle both unsigned and signed integers. Attached are two demo images. One is uint24-scale data stored in uint32; the other is int24 data stored in int32.
% a uint24-scale image stored in uint32
S = load('peppers_uint2432.mat');
inpict = S.inpict;
% cast and rescale to uint8
outclass = 'uint8';
ir = [0 2^24-1]; % for uint24-scale input
%ir = [-2^23 2^23-1]; % for int24-scale input
or = getrangefromclass(cast(1,outclass));
scalefactor = diff(or)/diff(ir);
outpict = cast((double(inpict) - ir(1))*scalefactor + or(1),outclass);
imshow(outpict)
% compare the converted image against the original
% image from which the 24b version was constructed
inpict0 = imread('peppers.png');
isequal(inpict0,outpict)
ans = logical
1
The above is a simple example which is only somewhat generalized. For a more general set of input and output classes/scales, it will not always be consistent with the conventions implied by tools like im2uint8()/im2int16(). I could certainly make the example more complicated, but there's no good reason to reinvent these wheels every time they're needed. MIMT imcast() now supports this sort of non-native integer scale data. The above example reduces to this:
% uint24-scale uint32 --> native-scale uint8
S = load('peppers_uint2432.mat');
outpict = imcast(S.inpict,'uint24','uint8'); % one line
In this explicit usage, the input and output can be any native class, or any non-native integer scale. We don't need to manually come up with the scale extents or anything. We don't need to remember the correct way to do the rescaling to keep the rounding behavior consistent between signed and unsigned outputs.
% int24-scale int32 --> unit-scale float
S = load('peppers_int2432.mat');
outpict = imcast(S.inpict,'int24','double'); % one line
That said, images represented in non-native integer scales are necessarily improperly-scaled for their class. This forces you to keep track of what the scale is. Neither imcast(), nor any other tool will be able to infer the intended scale from the class of the array anymore. While imcast() does support this sort of an array in explicit mode, the intent is only to support data import/export as in the prior two code snippets. I don't encourage trying to build an entire workflow around improperly-scaled image data.

Community Treasure Hunt

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

Start Hunting!

Translated by