[vtkusers] Problem using vtkDicomWriter

David Gobbi david.gobbi at gmail.com
Wed Jan 25 08:35:53 EST 2017


Hi Eddy,

The code is using a vtkDICOMCTGenerator to write an MR image, which is
definitely wrong.  Use the vtkDICOMMRGenerator, and make sure the meta data
matches the IOD:
http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.8.3.html

The standard says that BitsAllocated must be 16 for MR images, therefore an
8-bit MR image is non-standard and DICOM software may to refuse to display
it.  You should convert your data to 16-bit (In fact, it seems fishy that
you are working with unsigned char, since if you are writing a reformat of
an MR image, then wasn't the original MR image a 16-bit image?)

I can't answer about why Slicer is only showing one slice, as I don't
currently have Slicer installed.

 - David



On Wed, Jan 25, 2017 at 1:57 AM, Eddy Cappeau <edcpwk at gmail.com> wrote:

> Hi David,
>
> Here's the code below. This is almost the example of the api doc :
>
>     auto generator = vtkSmartPointer <vtkDICOMCTGenerator>::New();
>     vtkSmartPointer <vtkDICOMMetaData> meta = vtkSmartPointer
> <vtkDICOMMetaData>::New();
>
>     meta->SetAttributeValue(DC::PatientName, "Test");
>     meta->SetAttributeValue(DC::PatientID, "0000001");
>     meta->SetAttributeValue(DC::ScanOptions, "");
>     meta->SetAttributeValue(DC::ScanningSequence, "GR");
>     meta->SetAttributeValue(DC::SequenceVariant, "SP");
>     meta->SetAttributeValue(DC::ScanOptions, "");
>     meta->SetAttributeValue(DC::MRAcquisitionType, "2D");
>
>     vtkSmartPointer <vtkDICOMWriter> dicom_writer =
>         vtkSmartPointer <vtkDICOMWriter>::New();
>     dicom_writer->SetInputData(img);
>     dicom_writer->SetMetaData(meta);
>     dicom_writer->SetGenerator(generator);
>     dicom_writer->SetSeriesDescription("Sagittal Multi-planar Reformat");
>
>     // Set the output filename format as a printf-style string.
>     dicom_writer->SetFilePattern("%s/IM-0001-%04.4d.dcm");
>     // Set the directory to write the files into.
>     dicom_writer->SetFilePrefix(path.toStdString().c_str());
>     // Write the file.
>     dicom_writer->Write();
>
> Sorry, the use of an unsigned short type was a carreless mistake. The
> result is better with unsigned char,
> but I still see just one image of the serie on 3D Slicer. Is there
> something missing to have a complete serie ?
>
> I didn't know the vtkImageImport and I'll give it a try.
>
> Thanks,
>
> Eddy
>
>
> 2017-01-24 15:41 GMT+01:00 David Gobbi <david.gobbi at gmail.com>:
>
>> Hi Eddy,
>>
>> Can you provide the code that you used to write the image with
>> vtkDICOMWriter?  Here is an example:
>> http://dgobbi.github.io/vtk-dicom/doc/api/image_writer.html
>>
>> Creating an image with a loop that calls GetScalarPointer() for every
>> pixel is not very efficient, and casting to a "char *" when the data is
>> "unsigned short" is wrong: you are setting only 8 bits of each 16-bit
>> pixel, while leaving the other 8 bits uninitialized.  The vtkImageImport
>> filter is a better way of generating image data:
>> http://www.vtk.org/Wiki/VTK/Examples/Cxx/Images/ImageImport
>>
>>  - David
>>
>>
>> On Tue, Jan 24, 2017 at 2:51 AM, Eddy Cappeau <edcpwk at gmail.com> wrote:
>>
>>> Hi,
>>>
>>> I'd like to use the vtkDICOMWriter class to convert a vtkImage to a set
>>> of DICOM images.
>>>
>>> I've compile VTK with the vtkDICOM module enabled and followed the
>>> example from the pdf found on the github repository (
>>> http://dgobbi.github.io/vtk-dicom/doc/vtk-dicom.pdf).
>>>
>>>
>>> The image data is created like this :
>>>
>>>     auto  img = vtkSmartPointer < vtkImageData >::New();
>>>     img->SetOrigin(0, 0, 0);
>>>     img->SetDimensions(1024, 1024, numlayer);
>>>     img->SetSpacing(1, 1, 1);
>>>     img->AllocateScalars(VTK_UNSIGNED_SHORT, 1);
>>>
>>> and the data filled like this :
>>>
>>>            for (int n = 0; x < numlayer; n++) {
>>>                 for (int x = 0; x < 1024; x++) {
>>>                     for (int y = 0; y < 1024; y++) {
>>>                         char* pixel = static_cast<char*>(img->GetScalarPointer(x,
>>> y, n));
>>>                         pixel[0] = values[x][y];
>>>                     }
>>>
>>> I can load the converted result with paraview without problems.
>>> But with 3D Slicer, I can just load the first file of the serie and it
>>> display a blank image.
>>>
>>> What do I have to do to be able to load the images with both application
>>> ?
>>>
>>> Thanks,
>>>
>>> Eddy
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20170125/cd678768/attachment.html>


More information about the vtkusers mailing list