# How to write a DicomVolume from a DicomSeries without losing Header Infos.

**URL:** <https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443>\
**Category:** Beginner Questions\
**Created:** [September 7, 2020, 8:47pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443 "2020-09-07T20:47:38Z")\
**Posts on this page:** 17\
**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:** [September 7, 2020, 8:47pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/1 "2020-09-07T20:47:38Z")

</div>

Hi everyone,

I have read the DicomSeriesReadImageWrite2 [example](https://itk.org/Doxygen/html/Examples_2IO_2DicomSeriesReadImageWrite2_8cxx-example.html) .

It did work but i noticed the Dicom-header Infos are “losted”.  
All of slices have the same Dicom-header Infos and pixel spacing will be default 1. I tired many options about SetMetaDataDictionary/SetMetaDataDictionaryAarry but the problem persisted. Here is my code. I’ve simplified the “reader part”. of above example

> ```
> using PixelType = signed short;
> constexpr unsigned int Dimension = 3;
> using ImageType = itk::Image<PixelType, Dimension>;
> 
> using NamesGeneratorType = itk::GDCMSeriesFileNames;
> NamesGeneratorType::Pointer NameGenerator = NamesGeneratorType::New();
> 
> NameGenerator->SetUseSeriesDetails(true);
> NameGenerator->AddSeriesRestriction("0008|0021");
> 
> NameGenerator->SetGlobalWarningDisplay(false);
> NameGenerator->SetDirectory(myInputDirectory);
> using ReaderType = itk::ImageSeriesReader<ImageType>;
> ReaderType::Pointer reader = ReaderType::New();
> using ImageIOType = itk::GDCMImageIO;
> ImageIOType::Pointer dicomIO = ImageIOType::New();
> const ReaderType::FileNamesContainer & filenames = NameGenerator->GetInputFileNames();
> reader->SetImageIO(dicomIO);
> reader->SetFileNames(filenames);
> //reader->ForceOrthogonalDirectionOff();
> try {
> reader->Update();
> }
> catch (itk::ExceptionObject& ex) {
> std::cout << ex << std::endl;
> 
> }
> using ImageoutType = itk::Image<PixelType, 3>;
> using WriterType = itk::ImageSeriesWriter<ImageType, ImageoutType>;
> WriterType::Pointer writer = WriterType::New();
> writer->SetInput(reader->GetOutput());
> writer->SetImageIO(dicomIO);
> writer->SetFileName(myOutputDirectory+"\\xxx.dcm")
> writer->SetMetaDataDictionary(reader->GetMetaDataDictionary());
> 
> try {
> writer->Update();
> }
> catch (itk::ExceptionObject& ex) {
> std::cout << ex << std::endl;
> }
> 
> ```

---

<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:** [September 7, 2020, 9:28pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/2 "2020-09-07T21:28:37Z")

</div>

You taking n 2D files, and producing 1 3D file. There can be only 1 metadata item for regular stuff (e.g. flip angle), even if the metadata item in question had different values among input 2D slices. I am not sure whether you can save an array of metadata, but even if you can it is non-trivial DICOM trickery. @lassoan, @mihail.isakov or @mathieu.malaterre might offer more insight.

---

<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:** [September 8, 2020, 8:41am UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/3 "2020-09-08T08:41:40Z")

</div>

Thanks for your reply. Yes it is. There is only one metadata from n slice apply for volume I created. in this case all the slice in volume have the same image number and pixels spacing infos will lost.that is annoying. Furthermore there is also a tricky problem. When I use imageJ read the volume, and check the metadata ,Tag “0028|0030” did have the original XY pixel spacing but there is a symbol"\<" before the key. Then I use" variable= dicomIo-\> GetvaluefromTag(“0028|0031”, value)” variable will not be given any value which means this Tag is empty . I am confused

---

<div class="post-metadata">

**Author:** ![mihail.isakov](https://discourse.itk.org/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@mihail.isakov](https://discourse.itk.org/u/mihail.isakov)\
**Post date:** [September 8, 2020, 12:02pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/4 "2020-09-08T12:02:24Z")

</div>

FYI

> [@How to convert DICOM sequence images into a multi frame DICOM file.](https://discourse.itk.org/t/how-to-convert-dicom-sequence-images-into-a-multi-frame-dicom-file/3116/4):
>
> S. 1st example in the post Download [link](http://www.dclunie.com/pixelmed/software/index.html)

---

<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:** [September 8, 2020, 1:35pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/5 "2020-09-08T13:35:57Z")

</div>

So if i want to keep the metadata for each frame then i have to use this toolkit ?  
Is it possiable that i only use ITK to achieve this function?

---

<div class="post-metadata">

**Author:** ![mihail.isakov](https://discourse.itk.org/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@mihail.isakov](https://discourse.itk.org/u/mihail.isakov)\
**Post date:** [September 8, 2020, 2:27pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/6 "2020-09-08T14:27:43Z")

</div>

You can simply load image and save ITK image with .dcm extension with ITK writer, the result will be _Multi-frame Grayscale Word (or byte or true color) Secondary Capture Image_, it works good (for uniform images) and the image will be multi-frame too. Theoretically, in ITK you have access to DCMTK and GDCM libraries, so at very low level is mostly everything possible. But the task is rather difficult, IMHO. There are many question, what [storage class](http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_B.5.html#table_B.5-1) do you want to generate, etc.

**Edit** :  
I hope i have understood the task correctly, from the title “DicomVolume from DicomSeries” i have assumed you wish to create multi-frame image from classic series. They are different storage classes, eg, _MR Image Storage_ and _Enhanced MR Image Storage_ or _Legacy Converted Enhanced MR Image Storage_.

---

<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:** [September 8, 2020, 4:30pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/7 "2020-09-08T16:30:20Z")

</div>

Thanks for details reply. You understand my question right. I knew how to create a multi frame image. But the problem is that how can I create a multi frame dicom while it can also keep the original metadata for each frame. As you said they are different storage classes , so if I simply use itkwriter will not avoid losing the metadata . Am I right?

---

<div class="post-metadata">

**Author:** ![mihail.isakov](https://discourse.itk.org/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@mihail.isakov](https://discourse.itk.org/u/mihail.isakov)\
**Post date:** [September 8, 2020, 5:45pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/8 "2020-09-08T17:45:50Z")

</div>

If you simply use ITK writer - spacing, origin, orientation should be correct (for multi-frame secondary capture s. content of _shared_ and _per frame_ groups with e.g. _dcmdump_). Caution with non-uniform series, 3D volume is assumed. By default there will be no patient name/id/study id, but it is possible to add . If you don’t want multi-frame secondary capture, but e.g.convert mr classic series to mr enhanced or have non-uniform series - better try David Clunie’s java class, it could be fastest and correct solution.

**Edit** :  
with uniform i mean orthogonal and with equidistant slices, spacing can be different for all 3 axis

---

<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:** [September 8, 2020, 11:08pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/9 "2020-09-08T23:08:41Z")

</div>

The Series is uniform and from the same CT scan sequence. Even though the Multi-Frame Image can not keep the Pixelspacing.

I show you the screenshot from ImageJ ,the first two images are from Multi-Frame and last two images are from a single slice of orginal Series.  
. ![Snipaste_2020-09-09_00-43-13](https://discourse.itk.org/uploads/default/original/2X/d/d816df18c58c982c55f3158d107ef2d31b30ea7d.png) ![Snipaste_2020-09-09_00-46-05](https://discourse.itk.org/uploads/default/original/2X/3/37720ddc959633873e5d22ddd38bcb77083a7d6c.png) ![Snipaste_2020-09-09_00-46-57](https://discourse.itk.org/uploads/default/original/2X/3/3b5ea297a53c997cb4a9b1b8d7cdd3440eb66dd5.png) ![Snipaste_2020-09-09_00-47-29](https://discourse.itk.org/uploads/default/original/2X/b/b9ab06dc086162cf1b4a6cd71c5567d06e38bee8.png)

Tag “0028|0030” represent the Pixelspacing ,and in Multi-Frame file I created ,there is a symbol"\<" before the key Pixelspacing . and i wrorte the code:

```
std::string value;
dicomIo-> GetvaluefromTag(“0028|0030”, value)

```

`value` will not be assigned any value. And at the end of Metadata list, the ImageJ self-analyzed part，the pixel spacing is considered as 1 ,but it should be 0.085.  
This problem is due to the mechanism of dicom or i made mistake in my code? (code is above)  
Thanks again

---

<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:** [September 8, 2020, 11:48pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/10 "2020-09-08T23:48:11Z")

</div>

What voxel spacing ITK-SNAP and 3D Slicer report for `TOMO_unpadded.IMA`?

---

<div class="post-metadata">

**Author:** ![mihail.isakov](https://discourse.itk.org/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@mihail.isakov](https://discourse.itk.org/u/mihail.isakov)\
**Post date:** [September 9, 2020, 1:57am UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/11 "2020-09-09T01:57:19Z")

</div>

In multi-frame (sc or mr or ct) pixel spacing should be in shared or per-frame group, not at the root level like in single frame.

 ![Untitled](https://discourse.itk.org/uploads/default/original/2X/7/7336c4ec98cad636c107a5e9d9f4f99558ce3885.jpeg)

There should be no pixel spacing tag at root level.

---

<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:** [September 9, 2020, 8:52am UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/12 "2020-09-09T08:52:22Z")

</div>

To my surprise, in 3D slicer Image spacing is correct . But it doesn’t solve the problem that spacing not being able to read it in the code.

---

<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:** [September 9, 2020, 9:24am UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/13 "2020-09-09T09:24:26Z")

</div>

root level means the single frame in Multi frame file, right?

I seem to have a clue. That is, for multiframe files i created, i checked its **Standard SOP Classes** is Enhanced CT Image Storage , there shouldn’t be the 0028|0030 tag in single frame , but the pixel spacing is still somehow recorded in the multiframe file, so the image could correctly display . Am I right?  
If so , how could i read the pixel spacing in code?  
And i have also a Ultrasound Multi-frame Image , it has pixel spacing tag for each frame. and i can read it in code. This seems to contradict my conclusion above… 🤣

---

<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:** [September 9, 2020, 7:25pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/15 "2020-09-09T19:25:10Z")

</div>

Simply [reading the image](https://itk.org/ITKExamples/src/IO/ImageBase/ReadAnImage/Documentation.html) should give you the voxel spacing, available via `image->GetSpacing()`.

---

<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:** [September 10, 2020, 3:24pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/17 "2020-09-10T15:24:47Z")

</div>

with `image->GetSpacing()` . It works. The solution is so simple but It was a tortuous process. i have learned a lot from this discuss. Thanks for your 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:** [September 10, 2020, 3:28pm UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/18 "2020-09-10T15:28:23Z")

</div>

Thanks for telling me about the mechanism of the dicom storage class, I learned a lot, thanks again!

---

<div class="post-metadata">

**Author:** ![mihail.isakov](https://discourse.itk.org/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@mihail.isakov](https://discourse.itk.org/u/mihail.isakov)\
**Post date:** [September 12, 2020, 6:14am UTC](https://discourse.itk.org/t/how-to-write-a-dicomvolume-from-a-dicomseries-without-losing-header-infos/3443/19 "2020-09-12T06:14:46Z")

</div>

FYI

[https://dicom.innolitics.com/ciods](https://dicom.innolitics.com/ciods)
