How can i change ppm image resolution when I using Imread?
1 次查看(过去 30 天)
显示 更早的评论
For example,
a = imread("xxxx.ppm")
xxxx image resolution has default 255
So when I reading 1023 resolution ppm files, data is forcibly multiplied by 20.
How can I change ppm image resolution when I Using Imread?
please help me,
I'm sorry for the lack of readability because My English skill are not good
Thanks for reading.
3 个评论
DGM
2024-6-4
编辑:DGM
2024-6-4
Maybe I'm misreading things. According to the webdocs, imread() supposedly reduces all PPM files to uint8 output regardless of bitdepth -- but that doesn't seem to actually be true.
% this is uint10-scale data stored at 6B per pixel (uint16)
% this is an ascii-encoded (P3) PPM, which is what you should have
inpict = imread('pep_u10u16.ppm.fakename.txt');
% it's all there
[min(inpict(:)) max(inpict(:))]
% show it (in unit-scale)
imshow(double(inpict)/1023)
So since it works with this image containing uint10-scale data in a uint16 PPM, it's not clear why it wouldn't work with yours, unless I'm misinterpreting what your file is.
Again, you would have to attach the image file for us to know anything about the actual problem. For all I know, the file is being read correctly, but it wasn't written the way you think it was. I suspect they simply weren't written correctly.
采纳的回答
DGM
2024-6-4
编辑:DGM
2024-6-4
Good gravy. I finally figured out what you're doing.
You're writing your PPM files using 'maxvalue' set to 1023. This is what happens.
When you specify that maxvalue parameter, a full uint16-scale image will be written "as if" uint10. In other words, it will be grossly quantized such that a 0:65535 ramp will fit into the integers 0:1023 in the file. When the file is opened, that encoded data is then scaled back to uint16-scale. Accordingly, the values in the file and the decoded values differ by a factor of 64. So not only does it not do what you wanted, it would damage your data by quantization (if it weren't already quantized in the specified scale).
If you were to write a 0:1023 ramp stored in uint16 while specifying a maxvalue of 1023, the exact same thing happens. Your 1024-level ramp is quantized to a 16-level ramp. The literal values in the file are all in the range 0:15. When you read it back, you get the same grossly quantized ramp, scaled back up. Due to the quantizing, the maximum value is now 15*64 = 960 instead of 1023.
% a uint10-scale ramp stored in uint16
inpict10 = repmat(uint16(0:1023),[1 1 3]); % [0 1023], 1024 unique values
% the values are treated as uint16-scale and written in uint10-scale
maxval = 1023;
imwrite(inpict10,'pep_u10u16.ppm','maxval',maxval,'encoding','ascii')
% directly inspect the population of values present in the file
infile = readmatrix('pep_u10u16.ppm','filetype','text','numheaderlines',1);
infile = infile(~isnan(infile));
vf = unique(infile).' % [0 15], only 16 unique values
% read the file back
written = imread('pep_u10u16.ppm'); % uint16-scale again
vr = unique(written).' % [0 960], only 16 unique values
% the stored and read values differ by a factor of 64
double(vr(end))./double(vf(end))
You have two choices:
Option 1: Represent your data in its native scale inside the wider uint16 class. This will be simple to read and write, though everything which blindly reads the file will treat it as being uint16-scale, and consequently it will appear black because it contains no values above 1023. The comment above is an example.
Option 2: Rescale your data to uint16-scale and store it in uint16, while specifying the maxvalue of 1023. This seems like an extra convoluted way of doing things, with no sum benefit if your goal is to preserve the native uint10 scale. The image will be naturally displayed by any naive viewer, but it will be returned in uint16-scale. In other words, the image must be manually rescaled from [0 1023] to [0 65535] before writing, it's automatically rescaled back to [0 1023] during writing, then it's automatically scaled back to [0 65535] during read, and it must finally be manually rescaled again back to [0 1023]. Here's an example:
% a uint10-scale ramp stored in uint16
inpict10 = repmat(uint16(0:1023),[1 1 3]); % [0 1023]
% rescale from uint10-scale to uint16-scale
inpict16 = bitor(bitshift(inpict10, 16-10), bitshift(inpict10, 16-2*10)); % [0 65535]
% the values in the written file are in uint10-scale! [0 1023]
maxval = 1023;
imwrite(inpict16,'pep_u10u16.ppm','maxval',maxval,'encoding','ascii')
% read the file back
written = imread('pep_u10u16.ppm'); % [0 65535]
% rescale back to uint10-scale again
written = bitshift(written,-16+10); % [0 1023]
% prove it
[min(written(:)) max(written(:))]
isequal(inpict10,written)
更多回答(0 个)
另请参阅
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!