Как я могу прочитать изображение в формате RAW в MATLAB?
Я хочу открыть и прочитать .raw
изображение в MATLAB. Мой файл можно скачать здесь. Я пробовал следующие три фрагмента кода, но ни один из них не дает ожидаемых результатов.
Фрагмент кода #1
row=576; col=768;
fin=fopen('m-001-1.raw','r');
I=fread(fin,row*col,'uint8=>uint8');
Z=reshape(I,row,col);
Z=Z';
k=imshow(Z);
Это показывает эту картину:
Фрагмент кода № 2
f=fopen('m-001-1.raw');
a=fread(f);
input_img = reshape(a,768, 576, 3);
input_img = imrotate(input_img, -90);
imwrite(input_img, 'm-001-1.jpg');
Это сохраняет чистое (только белое) изображение в .jpg
формат.
Фрагмент кода № 3
id = fopen('m-001-1.raw', 'r');
x = fread(id, [576,768], 'short');
Когда я использую imshow(x)
эта картина показывает:
Как правильно прочитать эту картинку?
2 ответа
Код Питера (спасибо, кстати!) Работает, если предположить, что ваше изображение в градациях серого. Для цветных изображений вам нужно прочитать все байты как один одномерный массив, поскольку мы не можем использовать fread
читать данные в виде 3D-матрицы (по крайней мере, насколько я знаю...). Затем мы изменяем его, чтобы он стал трехмерной матрицей. После того, как мы изменим матрицу, обратите внимание, что это транспонированный результат. Таким образом, нам придется либо транспонировать каждый канал независимо, либо вы можете умно комбинировать flipdim
а также imrotate
сделать 3D транспонирование для нас. Я бы повернул изображение так, чтобы оно было на 90 градусов по часовой стрелке, но это отражало бы зеркальное отражение изображения по столбцам. Я тогда использую flipdim
со вторым параметром как 2
поскольку я хочу отразить отражение через колонки, чтобы вернуть исходное изображение.
Таким образом, то, что вам на самом деле нужно сделать, это:
row=576; col=768;
fin=fopen('m-001-1.raw','r');
I=fread(fin, col*row*3,'uint8=>uint8'); %// Read in as a single byte stream
I = reshape(I, [col row 3]); %// Reshape so that it's a 3D matrix - Note that this is column major
Ifinal = flipdim(imrotate(I, -90),2); % // The clever transpose
imshow(Ifinal);
fclose(fin); %// Close the file
Что я получаю, это изображение:
В качестве альтернативы вы, конечно, можете использовать код Питера, но вы бы использовали его так, чтобы вы восстанавливали изображение по одной цветовой плоскости за раз. Другими словами, вы можете сделать это:
row=576; col=768;
fin=fopen('m-001-1.raw','r');
I1=fread(fin, [col row],'uint8=>uint8'); %// Red channel
I2=fread(fin, [col row],'uint8=>uint8'); %// Green channel
I3=fread(fin, [col row],'uint8=>uint8'); %// Blue channel
I1 = I1.'; I2 = I2.'; I3 = I3.'; %// Transpose each channel separately
Ifinal = cat(3, I1, I2, I3); %// Create 3D matrix
imshow(Ifinal);
fclose(fin);
Вы получите точно такое же изображение, как указано выше.
Ваши размеры строк / столбцов поменялись местами. Поскольку массивы MATLAB являются основными столбцами, а растровые изображения обычно хранятся в основных строках, вам необходимо прочитать изображение как матрицу [col row], а затем транспонировать ее.
row=576; col=768;
fin=fopen('m-001-1.raw','r');
I=fread(fin, [col row],'uint8=>uint8');
Z=I';
k=imshow(Z)
Репликация изображения происходит из-за того, что у вас короткие 768-576 = 192 пикселя на строку, поэтому каждая строка постепенно отклоняется от этой суммы. После 4 строк вы составили разницу (4*192 = 768), поэтому у вас есть репликация из 4 изображений.