niftiwrite で画像タグ情報を編集し書き込みたいとき,エラーが出て出力できません.
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
0 개 추천
画像読み込み~演算処理後に,PixelDimensionsなどタグ情報が[1 1 1]に変わっていることから,もともとの画像情報と同じ[2 2 2]に上書きしたかったため,
niftiwrite(Image,'PixelDimensions', [2 2 2])
とすると,以下のエラーが出てタグ情報を編集できません.niftiinfoにて元画像のタグ情報ではPixelDimensionsは存在します.
ご教示いただければ幸いです.よろしくお願いいたします.
エラー: niftiwrite>parseInputs (行 175)
'Info' の値は無効です。関数 @(x)validateHeader(V,x) を満たさなければなりません。
エラー: niftiwrite (行 89)
[V, path, filename, params] = parseInputs(V, filename, varargin{:});
채택된 답변
Atsushi Ueno
2022년 10월 1일
편집: Atsushi Ueno
2022년 10월 3일
1 개 추천
niftiwrite関数にタグ情報を(追記:任意に)変更する機能はありません。niftiinfo関数でタグ情報を読み込み内容を変更してからniftiwrite関数に渡せば、それをNIFTI画像ファイルに書き込んでくれます。
Image = niftiread('brain.nii'); % 元画像の読み込み
info = niftiinfo('brain.nii'); % 元画像からタグ情報の読み取り
info.PixelDimensions % PixelDimensionsが[1 1 1]になっている
ans = 1×3
1 1 1
info.PixelDimensions = [2 2 2] % PixelDimensionsを[2 2 2]に変更する
info = struct with fields:
Filename: '/MATLAB/toolbox/images/imdata/brain.nii'
Filemoddate: '01-Feb-2017 15:22:59'
Filesize: 1376608
Version: 'NIfTI1'
Description: ''
ImageSize: [256 256 21]
PixelDimensions: [2 2 2]
Datatype: 'uint8'
BitsPerPixel: 8
SpaceUnits: 'Unknown'
TimeUnits: 'None'
AdditiveOffset: 0
MultiplicativeScaling: 0
TimeOffset: 0
SliceCode: 'Unknown'
FrequencyDimension: 0
PhaseDimension: 0
SpatialDimension: 2
DisplayIntensityRange: [0 0]
TransformName: 'None'
Transform: [1×1 affine3d]
Qfactor: 1
raw: [1×1 struct]
niftiwrite(Image,'NIfTI_file_name.nii',info); % 元画像を変更済タグ情報と共にファイルに書き込む
認識される構文の種類は下記の3種類のいずれかを選択する必要があり、2番目の引数組み合わせを使います。
댓글 수: 4
KT
2022년 10월 2일
Image = niftiread('brain.nii'); % 元画像の読み込み
info = niftiinfo('brain.nii'); % 元画像からタグ情報の読み取り
[画像処理]
niftiwrite(ImageProc,'NIfTI_file_name.nii')
info = niftiinfo('ImageProc');
info.PixelDimensions = [2 2 2] % 処理画像でなぜかPixelDimensionsが変わっているため,[2 2 2]に変更する
info.Transform.T = [-2 0 0 0; 0 2 0 0; 0 0 2 0;1 -1 -1 1];
info.raw.pixdim = [-1, 2, 2, 2, 0, 0, 0, 0]
niftiwrite(ImageProc,'NIfTI_file_name.nii', info)
例に挙げて頂いた画像を読み込み,処理後の画像をImageProcとすると,まずは書き出す必要があるため,niftiwriteで書き込み,書き込んだファイルをniftiinfoでタグ情報を読み取り変更したのち,再度書き込みする必要があるでしょうか.
上記方法でPixelDimensionsは変更できましたが,Transform.Tやrawは変更できませんが方法はありますでしょうか.
Atsushi Ueno
2022년 10월 2일
>例に挙げて頂いた画像を読み込み,処理後の画像をImageProcとすると,まずは書き出す必要があるため,niftiwriteで書き込み,書き込んだファイルをniftiinfoでタグ情報を読み取り変更したのち,再度書き込みする必要があるでしょうか.
⇒その必要は無いと思います。画像とタグ情報は同時にファイル書き込み可能です。
>niftiwrite(V,filename,info) は、ボリューム データ V (info からのファイル メタデータを含む) をファイルに書き込みます。メタデータがイメージのコンテンツおよびサイズと一致しない場合、niftiwrite はエラーを返します。
>上記方法でPixelDimensionsは変更できましたが,Transform.Tやrawは変更できませんが方法はありますでしょうか.
info.PixelDimensions、info.Transform.T、info.raw.pixdimそれぞれは変更出来ています。info構造体として表示しようとすると端折られて表示されないだけです。それぞれ変更前と変更後の内容を表示してみました。変更内容は間違いなく反映されています。
Image = niftiread('brain.nii'); % 元画像の読み込み
info = niftiinfo('brain.nii'); % 元画像からタグ情報の読み取り
info.PixelDimensions % 変更前
ans = 1×3
1 1 1
info.PixelDimensions = [2 2 2]; % 処理画像でなぜかPixelDimensionsが変わっているため,[2 2 2]に変更する
info.PixelDimensions % 変更後
ans = 1×3
2 2 2
info.Transform.T % 変更前
ans = 4×4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
info.Transform.T = [-2 0 0 0; 0 2 0 0; 0 0 2 0;1 -1 -1 1]; % 変更
info.Transform.T % 変更後
ans = 4×4
-2 0 0 0
0 2 0 0
0 0 2 0
1 -1 -1 1
info.raw.pixdim % 変更前
ans = 1×8
1 1 1 1 0 0 0 0
info.raw.pixdim = [-1, 2, 2, 2, 0, 0, 0, 0]; % 変更
info.raw.pixdim % 変更後
ans = 1×8
-1 2 2 2 0 0 0 0
niftiwrite(Image,'NIfTI_file_name.nii', info)
Atsushi Ueno
2022년 10월 3일
>例に挙げて頂いた画像を読み込み,処理後の画像をImageProcとすると,まずは書き出す必要があるため,niftiwriteで書き込み,書き込んだファイルをniftiinfoでタグ情報を読み取り変更したのち,再度書き込みする必要があるでしょうか.
⇒「その必要は無いと思います」と回答しましたが私の誤解です。その必要がありますね。
niftiinfo関数はNIFTI画像ファイルからタグ情報を得ますが、タグ情報と画像データは互いに独立しているので、画像データを処理しても「タグ情報が付いてこない」事になります。niftiwrite関数で画像データをファイルに書き込むと、どういう仕組みか分かりませんがヘッダ情報を書き込んでいます。(下記プログラム参照)。これをまたniftiinfo関数でタグ情報として取り出せば「画像データにタグ情報が付いてくる」事になりますね。
※MATLABのドキュメントでは「タグ情報」は「メタデータ」と書かれています。このQAでは「タグ情報」に統一します。
>エラー部分のクラスを一致させれば書き込み可能と考えますがどの部分が不一致となるのでしょうか.
私はこのNIFTI画像フォーマットに対して無知なので判りません。ドキュメントには「メタデータがイメージのコンテンツおよびサイズと一致しない場合、niftiwrite はエラーを返します」と書いてあるので、画像データとタグ情報が矛盾している事は間違いなさそうです。
type niftiinfo
function metadata = niftiinfo(filename)
%NIFTIINFO Read metadata from NIfTI file.
% METADATA = NIFTIINFO(FILENAME) reads the header of the NIfTI file named
% in the string or character vector FILENAME and returns all its contents
% in a MATLAB structure called METADATA. If the file extension is not
% specified, NIFTIINFO looks for a '.nii' file or its gzipped version
% (with extension '.nii.gz'). If that is not found, it looks for a '.hdr'
% file or its gzipped version (with extension '.hdr.gz'), and then a
% '.img' file or its gzipped version (with extension '.img.gz'). If it
% cannot find any of these files, NIFTIINFO returns an error.
%
% References:
% -----------
% [1] Cox, R.W., Ashburner, J., Breman, H., Fissell, K., Haselgrove, C.,
% Holmes, C.J., Lancaster, J.L., Rex, D.E., Smith, S.M., Woodward, J.B.
% and Strother, S.C., 2004. A (sort of) new image data format standard:
% Nifti-1. Neuroimage, 22, p.e1440.
%
% Example 1
% ---------
% %Viewing metadata fields from a NIfTI header file.
%
% % Load metadata from 'brain.nii'.
% info = niftiinfo('brain.nii');
%
% % Display the pixel dimensions of this file
% info.PixelDimensions
%
% % Display the raw header content
% info.raw
%
% % Display the intent code from the raw structure
% info.raw.intent_code
%
% See also NIFTIREAD, NIFTIWRITE.
% Copyright 2016-2017 The MathWorks, Inc.
narginchk(1,1);
filename = matlab.images.internal.stringToChar(filename);
NF = images.internal.nifti.niftiFile(filename);
fileDetails = dir(NF.HeaderFileName);
metadata.Filename = fullfile(fileDetails.folder, fileDetails.name);
metadata.Filemoddate = fileDetails.date;
metadata.Filesize = fileDetails.bytes;
NV = images.internal.nifti.niftiImage(NF.FileWithHeader);
% Get the simplified structure from niftiImage.
simpleStruct = NV.simplifyStruct();
% Copy simplified fields into metadata.
fields = fieldnames(simpleStruct);
for i = 1:numel(fields)
metadata.(fields{i}) = simpleStruct.(fields{i});
end
% Finally. append the raw struct to fileInfo.
metadata.raw = NV.header;
end
type niftiwrite
function niftiwrite(V, filename, varargin)
%NIFTIWRITE Write images as NIfTI files.
% NIFTIWRITE(V, FILENAME) writes a '.nii' file using the image data from
% V. By default, NIFTIWRITE creates a 'combined' NIfTI file that contains
% both metadata and volumetric data, giving it the '.nii' file extension.
% NIFTIWRITE populates the file metadata using appropriate default values
% and volume properties like size and data type.
%
% NIFTIWRITE(V, FILENAME, METADATA) writes a '.nii' file using the image
% data from V and metadata from METADATA. NIFTIWRITE creates a 'combined'
% NIFTI file, giving it the file extension '.nii'. If the metadata does
% not match the image contents and size, NIFTIWRITE returns an error.
%
% NIFTIWRITE(____, Name, Value) writes a '.nii' file using options
% specified in the Name Value pairs, described below.
%
% Optional Name-Value parameters include:
%
% 'Combined' - true (default) or false. If true, NIFTIWRITE
% creates one file with the file extension '.nii'.
% If false, NIFTIWRITE creates two files. One file
% contains metadata and has the file extension
% '.hdr'. The other files contains the volumetric
% data and has the file extension '.img'.
% NIFTIWRITE uses the file name you specified in
% FILENAME for both files.
%
% 'Compressed' - false(default) or true. If true, NIFTIWRITE
% compresses the generated file (or files) using
% gzip encoding, giving the file the .gz file
% extension as well as the NIFTI file extension.
%
% 'Endian' - 'little' (default) or 'big'.
% Controls the endianness of the data NIFTIWRITE
% writes to the file.
%
% 'Version' - 'NIfTI1' or 'NIfTI2'. Specifies the NIfTI format
% the data is to be written in. Default value
% depends on the maximum value of the dimensions
% of the volumetric data. The default value is
% 'NIfTI1' unless the maximum size in any
% dimension is more than 32767.
%
% References:
% -----------
% [1] Cox, R.W., Ashburner, J., Breman, H., Fissell, K., Haselgrove, C.,
% Holmes, C.J., Lancaster, J.L., Rex, D.E., Smith, S.M., Woodward, J.B.
% and Strother, S.C., 2004. A (sort of) new image data format standard:
% Nifti-1. Neuroimage, 22, p.e1440.
%
% Example 1
% ---------
% % This example illustrates writing a median filtered volume to a .nii
% % file.
%
% % Load a NIfTI image using its .nii file name.
% V = niftiread('brain.nii');
%
% % Filter the image in 3D using a 3-by-3-by-3 median filter.
% V = medfilt3(V);
%
% % Visualize the volume
% volshow(V)
%
% % Write the image to a .nii file. This uses default header values.
% niftiwrite(V, 'outbrain.nii');
%
% Example 2
% ---------
% % This example illustrates modifying the header structure and re-saving
% % a .nii file.
%
% % Load a NIfTI image using its .nii file name.
% info = niftiinfo('brain.nii');
% V = niftiread(info);
%
% % Edit the description of the file.
% info.Description = 'Modified using MATLAB R2017b';
%
% % Write the image to a .nii file.
% niftiwrite(V, 'outbrain.nii', info);
%
% See also NIFTIINFO, NIFTIREAD.
% Copyright 2016-2021 The MathWorks, Inc.
matlab.images.internal.errorIfgpuArray(V, filename, varargin{:});
[V, path, filename, params] = parseInputs(V, filename, varargin{:});
if strcmp(params.Endian, 'little')
machineFmt = 'ieee-le';
else
machineFmt = 'ieee-be';
end
headerStruct = params.Info;
if params.Combined
NV = images.internal.nifti.niftiImage(headerStruct);
fid = fopen([filename '.nii'], 'w', machineFmt);
% write header.
[fid, headerBytes] = NV.writeHeader(fid, machineFmt);
assert(headerBytes == 348||headerBytes == 540);
% Write empty data until vox_offset
skipBytes = double(headerStruct.vox_offset) - headerBytes;
fwrite(fid, zeros(1,skipBytes), 'uint8');
% write image data.
fid = NV.writeImage(V, fid, machineFmt);
fclose(fid);
if params.Compressed
gzip([filename '.nii'], path);
delete([filename '.nii']);
end
else
headerStruct.vox_offset = 0; % pixels start from first byte.
NV = images.internal.nifti.niftiImage(headerStruct);
headerfid = fopen([filename '.hdr'], 'w', machineFmt);
% write header.
[headerfid, headerBytes] = NV.writeHeader(headerfid, machineFmt);
assert(headerBytes == 348||headerBytes == 540);
fclose(headerfid);
% write image data.
imagefid = fopen([filename '.img'], 'w', machineFmt);
imagefid = NV.writeImage(V, imagefid, machineFmt);
fclose(imagefid);
if params.Compressed
gzip([filename '.hdr'], path);
gzip([filename '.img'], path);
delete([filename '.hdr']);
delete([filename '.img']);
end
end
end
%--------------------------------------------------------------------------
% Input Parsing
%--------------------------------------------------------------------------
function [V, fPath, fName, params] = parseInputs(V, fName, varargin)
varargin = matlab.images.internal.stringToChar(varargin);
% V has to be numeric, and of specific data types.
if ~isnumeric(V)
error(message('images:nifti:volumeMustBeNumeric'))
end
% filename needs to be a string or a character vector.
fName = matlab.images.internal.stringToChar(fName);
if ~ischar(fName)
error(message('images:nifti:filenameMustBeStringOrChar'))
end
[fPath, filenameOnly] = fileparts(fName);
if ~isempty(fPath)
fName = [fPath, filesep, filenameOnly];
else
fName = filenameOnly;
end
% Parse the PV pairs
parser = inputParser;
parser.addParameter('Combined', true, @(x)canBeLogical(x));
parser.addParameter('Compressed', false, @(x)canBeLogical(x));
parser.addParameter('Endian', 'little', @(x)ischar(x));
parser.addParameter('Version', 'NIfTI1', @(x)validateVersion(x));
parser.addOptional('Info', [], @(x)validateHeader(V,x));
parser.parse(varargin{:});
params.Combined = parser.Results.Combined ~= 0;
params.Compressed = parser.Results.Compressed ~= 0;
params.Endian = validatestring(parser.Results.Endian, {'little', 'big'});
params.Version = validatestring(parser.Results.Version, {'NIfTI1', 'NIfTI2'});
% If Version is not specified but Info is present
if any(strcmp(parser.UsingDefaults,'Version'))&&~isempty(parser.Results.Info)
params.Version = parser.Results.Info.Version;
end
%Default value of Version for size greater than 32767 is 'NIfTI2'
if any(strcmp(parser.UsingDefaults,'Version'))
if any(size(V)>32767)
params.Version = 'NIfTI2';
end
end
if strcmp(params.Version,'NIfTI1')
if any(size(V)>32767)
error(message('images:nifti:sizeTooBigNIfTI1'));
end
end
if isempty(parser.Results.Info)
params.Info = images.internal.nifti.niftiImage.niftiDefaultHeader(...
V, params.Combined, params.Version);
else
params.Info = images.internal.nifti.niftiImage.toRawStruct(...
parser.Results.Info, params.Combined, params.Version);
end
end
function T = validateVersion(version)
if ~ischar(version)
error(message('images:nifti:invalidVersion'));
else
T = true;
end
end
function TF = canBeLogical(input)
if isnumeric(input) || islogical(input)
TF = true;
else
TF = false;
end
end
function isHeader = validateHeader(V, simpleStruct)
if isstruct(simpleStruct)
if ~(isequal(simpleStruct.Datatype, class(V)))
error(message('images:nifti:volumeClassMustMatchHeader'))
end
% Allow trailing singleton dimensions in info.
dimsWithSingletonExpansion = max(ndims(V), numel(simpleStruct.ImageSize));
if ~(isequal(simpleStruct.ImageSize, size(V, 1:dimsWithSingletonExpansion)))
error(message('images:nifti:volumeSizeMustMatchHeader'))
end
if ~(length(simpleStruct.Description) <= 80)
error(message('images:nifti:descriptionLessThan80'))
end
if isfield(simpleStruct, 'AuxiliaryFile') && ...
~(length(simpleStruct.AuxiliaryFile) <= 24)
error(message('images:nifti:auxiliaryFileLessThan24'))
end
if isfield(simpleStruct, 'IntentDescription') && ...
~(length(simpleStruct.IntentDescription) <= 16)
error(message('images:nifti:intentMustBeLessThan16'))
end
isHeader = true;
else
isHeader = false;
end
end
KT
2022년 10월 6일
Uenoさま 返信ありがとうございました。 ご教示頂いた方法で、関連しそうなタグをいくつか書き込むことでうまくいきました。 今後とも宜しくお願い致します。
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 ファイルからのイメージ データの読み取りと書き込み에 대해 자세히 알아보기
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)