# how to wirte the dicom tags?(update my code)

**URL:** https://discourse.itk.org/t/how-to-wirte-the-dicom-tags-update-my-code/2896
**Category:** Beginner Questions
**Tags:** dicom
**Created:** [April 2, 2020, 8:49pm UTC](https://discourse.itk.org/t/how-to-wirte-the-dicom-tags-update-my-code/2896 "2020-04-02T20:49:16Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Amnesie](https://discourse.itk.org/user_avatar/discourse.itk.org/amnesie/32/1341_2.png) [@Amnesie](https://discourse.itk.org/u/Amnesie)
#### Post date: [April 2, 2020, 8:49pm UTC](https://discourse.itk.org/t/how-to-wirte-the-dicom-tags-update-my-code/2896/1 "2020-04-02T20:49:16Z")

</div>

hello every one,  
i am a new user with itk, Here is my question :  
how to automatic put some dicom tags in dicom when i turn raw volume data into dicom .?

I wrote some codes to make 3D volumen data in 2d slice , it works , but the 2d-dicom slice does not have any Dicom tags , how can i manually create them and write in dicom?  
Anyone knows the solutions or give me some Hits?  
here is my code,

> Blockquote  
> int main(int argc, char \*\* argv)  
> {  
> // Verify the number of parameters in the command line  
> if (argc \< 3)  
> {  
> std::cerr \<\< "Usage: " \<\< std::endl;  
> std::cerr \<\< argv[0] \<\< " input3DImageFile output2DImageFile " \<\< std::endl;  
> std::cerr \<\< " sliceNumber " \<\< std::endl;  
> return EXIT\_FAILURE;  
> }

```
using InputPixelType = float;
using OutputPixelType = unsigned short;//if change"short"to float the slice will be better but bigger

using InputImageType = itk::Image<InputPixelType, 3>;// 3D Volume
using OutputImageType = itk::Image<OutputPixelType, 2>;//2d slice

using ReaderType = itk::ImageSeriesReader<InputImageType>;//reader
using WriterType = itk::ImageSeriesWriter<InputImageType, OutputImageType>;//serieswriter

using RAWImageIOType = itk::RawImageIO<InputPixelType,3>;//use rawimageIo because input raw volume
using OUTImageIOType = itk::GDCMImageIO; //use GDCMImageIO because save as dicom slice

OUTImageIOType::Pointer gdcmImageIo = OUTImageIOType::New();// just pointer
RAWImageIOType::Pointer rawimageio = RAWImageIOType::New();// pointer+1

using NameGeneratorType = itk::NumericSeriesFileNames; //a NameGenerator magic!
using GDICOMTYPE = itk::GDCMSeriesFileNames; //a SeriesNameGenerator magic!
GDICOMTYPE::Pointer sliceNumberGenerator = GDICOMTYPE::New();//pointer+2
//sliceNumberGenerator->SetUseSeriesDetails(true);
//sliceNumberGenerator->AddSeriesRestriction("0020 | 0013");

////////////////////////////////////////////Set up how to read raw volume///////////////////////////////////
rawimageio->SetDimensions(0, 1289);					
rawimageio->SetDimensions(1, 2617);
rawimageio->SetDimensions(2, 49);

rawimageio->SetOrigin(0, 0.0); // 图像原点, volume origin
rawimageio->SetOrigin(1, 0.0);
rawimageio->SetOrigin(2, 0.0);

rawimageio->SetSpacing(0, 0.085); //像素距离,pixel spacing
rawimageio->SetSpacing(1, 0.085);
rawimageio->SetSpacing(2, 1.0);

rawimageio->SetFileTypeToBinary(); // 二进制方式打开, read with Binary method

rawimageio->SetFileDimensionality(2); // 读取二维数据,read 2 Dimension data
rawimageio->SetByteOrderToLittleEndian();//no idea but it must be here

rawimageio->SetNumberOfComponents(1); // 单个像素的位数
rawimageio->SetPixelType(itk::ImageIOBase::SCALAR); // 像素类型
rawimageio->SetComponentType(itk::ImageIOBase::FLOAT); // 像素类型
rawimageio->SetHeaderSize(0);//just data volume no header in raw ,so set 0

////////////////////////////////////////////Set up how to write raw volume///////////////////////////////////
gdcmImageIo->SetSpacing(0, 0.085);  
gdcmImageIo->SetSpacing(1, 0.085);
gdcmImageIo->SetNumberOfComponents(1); // 单个像素的位数
gdcmImageIo->SetPixelType(itk::ImageIOBase::SCALAR); // 像素类型
gdcmImageIo->SetLoadPrivateTagsDefault;

////////////////////////////////////////////Set up the Read/write Directory///////////////////////////////////

const char * inputFilename = argv[1];//"F:/ITKTrz/2020401reader/Volume00000_float_1289x2617x49.raw";
const char * outputDirectory = argv[2];//"F:/ITKTrz/2020401reader/";
itksys::SystemTools::MakeDirectory(outputDirectory);//if not exist the outputDirectory then create 

//sliceNumberGenerator->SetOutputDirectory(outputDirectory);//outputDirectory

ReaderType::Pointer reader = ReaderType::New();//pointer
WriterType::Pointer writer = WriterType::New();//pointer
NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();//point
reader->SetFileName(inputFilename);//set up
reader->SetImageIO(rawimageio);//set up

////////////////////////////////////////////NameGenerator magic the name part!///////////////////////////////////
std::string format = "DICOM_";
std::string formatSlice = "%03d.";
std::string formatExtension = ".ima"; // filename extension
format = std::string(outputDirectory) +format+ formatSlice+formatExtension;// user can change the format of the dicom slice
nameGenerator->SetSeriesFormat(format.c_str());

//////////////////////////////////I wanna automatic set dicom header for each dicom slice but not work ,it will be all the same dicom header /////////////////////////////////////////////////////////////////////////////
int AcquisitionNumber = 1;
int InstanceNumber = 0;
int ImagePositionPatient[3] = { 111,111,11 };
int SliceLocation = 0;
itk::MetaDataDictionary & dict = gdcmImageIo->GetMetaDataDictionary();//MetaDataDictionary is about dicom header
//using itr = itk::MetaDataDictionary::Iterator;
std::string tagkey;
std::string value;
//std::string value2 = std::to_string(start[2]);
tagkey = "0020|0012";
value = "value2";//"Acquisition Number	";
itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
tagkey = "0020|0013";
value = InstanceNumber++;//"Instance Number";
itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
tagkey = "0020|0032";
value = "Image Position Patient";
itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
tagkey = "0020|1041";
value = InstanceNumber++;//" Slice Location";
itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
tagkey = "0008|0060";
value = "CT";//" Slice Location";
itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
tagkey = "0020|000D";
value = "1.3.12.2.1107.5.12.7.310.30000020033006414815200000004";//" Slice Location";
itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
tagkey = "0020|000E";
value = "1.3.12.2.1107.5.12.7.310.30000020033006414818900000667";//" Series Instance UID ";

reader->SetMetaDataDictionary(dict);

try
{
	reader->Update();
}
catch ( itk::ExceptionObject & excp)
{
	std::cerr << "Exception thrown while reading the image" << std::endl;
	std::cerr << excp << std::endl;
}

////////////////////////////////////////////NameGenerator magic!how to extract slice from volume///////////////////////////////////

InputImageType::Pointer inputImage = reader->GetOutput();
InputImageType::RegionType region = inputImage->GetLargestPossibleRegion();
InputImageType::IndexType start = region.GetIndex();
InputImageType::SizeType size = region.GetSize();

const unsigned int firstSlice = start[2];
const unsigned int lastSlice = start[2] + size[2] - 1;
nameGenerator->SetStartIndex(firstSlice);
nameGenerator->SetEndIndex(lastSlice);
nameGenerator->SetIncrementIndex(1);

writer->SetFileNames(nameGenerator->GetFileNames());//SetFileNames
writer->SetImageIO(gdcmImageIo);
writer->SetInput(reader->GetOutput());
try
{
	writer->Update();
}
catch (itk::ExceptionObject & err)
{
	std::cerr << "ExceptionObject caught !" << std::endl;
	std::cerr << err << std::endl;
	return EXIT_FAILURE;
}

```

Thanks!!!

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [April 3, 2020, 1:25pm UTC](https://discourse.itk.org/t/how-to-wirte-the-dicom-tags-update-my-code/2896/2 "2020-04-03T13:25:40Z")

</div>

> [@Amnesie](#):
>
> reader-\>SetMetaDataDictionary(dict);

Try instead: `writer->SetMetaDataDictionary(dict);`

---

<div class="post-metadata">

### Author: ![Amnesie](https://discourse.itk.org/user_avatar/discourse.itk.org/amnesie/32/1341_2.png) [@Amnesie](https://discourse.itk.org/u/Amnesie)
#### Post date: [April 3, 2020, 4:24pm UTC](https://discourse.itk.org/t/how-to-wirte-the-dicom-tags-update-my-code/2896/3 "2020-04-03T16:24:04Z")

</div>

Thank your answer!! but it didn`t work when i change the “reader” to “writer”.

I think the problem is that i used “ImageSeriesWriter” and “nameGenerator” ,while the “SeriesWriter” can in one-time automatic save/extract all the slices and save their information （or not explicit, at least there is no iterator in my code）. therefore dicom Tags part can not update himself.

I want every Slice at least has his own “Acquisition Number”,for example first slice should be 0 then second slice is 1 and so on…

---

<div class="post-metadata">

### Author: ![jond01](https://discourse.itk.org/user_avatar/discourse.itk.org/jond01/32/1367_2.png) [@jond01](https://discourse.itk.org/u/jond01)
#### Post date: [April 7, 2020, 1:29pm UTC](https://discourse.itk.org/t/how-to-wirte-the-dicom-tags-update-my-code/2896/4 "2020-04-07T13:29:31Z")

</div>

Try to use:  
`writer->SetMetaDataDictionaryArray(mdictArr);`  
`mdictArr` is a vector of metadata dictionaries for each slice.  
[This example](https://itk.org/Doxygen50/html/WikiExamples_2DICOM_2ResampleDICOM_8cxx-example.html) may help.

---

<div class="post-metadata">

### Author: ![Amnesie](https://discourse.itk.org/user_avatar/discourse.itk.org/amnesie/32/1341_2.png) [@Amnesie](https://discourse.itk.org/u/Amnesie)
#### Post date: [April 13, 2020, 8:05pm UTC](https://discourse.itk.org/t/how-to-wirte-the-dicom-tags-update-my-code/2896/6 "2020-04-13T20:05:00Z")

</div>

Thank you so much!sorry for so late reply , these days i was working on other things. this example is very inspiring ! But in this example the Tags of new Slice is copy from the olds. Still, there’s a lot of useful functions and classes in there that I didn’t know about before. I will try it later . Thank you again
