フィルターのクリア

How can i change ppm image resolution when I using Imread?

10 ビュー (過去 30 日間)
경현
경현 2024 年 6 月 3 日
コメント済み: 경현 2024 年 6 月 5 日
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 件のコメント
경현
경현 2024 年 6 月 3 日
編集済み: 경현 2024 年 6 月 3 日
(1) For example, a = imread("xx.ppm") (xx.ppm has 1023 resolutioin)
'a' file's data has multiplied by 64, because MATLAB Imread ppm default resolution is 255
I think this problem is when I read 255 resolution ppm files, this file data has uint8
but 1023 resolution file data has uint16
I want to read pure data with 1023 resolution
(2) sorry, my mistake. Not 20 but 64
DGM
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(:))]
ans = 1x2
0 1023
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% 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
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
vf = 1x16
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% read the file back
written = imread('pep_u10u16.ppm'); % uint16-scale again
vr = unique(written).' % [0 960], only 16 unique values
vr = 1x16
0 64 128 192 256 320 384 448 512 576 640 704 768 832 896 960
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% the stored and read values differ by a factor of 64
double(vr(end))./double(vf(end))
ans = 64
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(:))]
ans = 1x2
0 1023
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
isequal(inpict10,written)
ans = logical
1
  1 件のコメント
경현
경현 2024 年 6 月 5 日
Thank you very much for your thoughtful reply.
I think it will be very helpful to me.
Have a nice day.

サインインしてコメントする。

その他の回答 (0 件)

製品

Community Treasure Hunt

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

Start Hunting!

Translated by