[Dcmlib] converting itk,vtk or any other 3D images into dicom.

jean-michel.rouet at philips.com jean-michel.rouet at philips.com
Thu Nov 4 13:45:54 CET 2004


Salut Mathieu, Salut la liste...

J'ai tenté quelques essais, mais ca rate quand meme pas mal.
Ce que j'essaye de faire, c'est lire une image dicom valide, changer 
quelques champs, lire en parallele une image vtk (ou autre), copier les 
informations de l'une vers l'autre, et sauver le tout dans une serie 
d'images dicom.

j'ai écrit ca, mais ca fait un peu n'importe quoi (l'image créée est 
lisible, mais le contenu n'a rien a voir avec ce que j'attends, elle est 
pleine de noir)! Est-ce que je fais qqchose de mal dans ce code ???

JM

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "gdcmHeader.h"
#include "gdcmFile.h"
#include "gdcmUtil.h"

#define USAGE "USAGE: Input3DImage InputDicomSample OutputDirectory"

using namespace std;

const unsigned int Dimension = 3;


// pixel types
typedef short   PixelType;

//image types 
typedef itk::Image< PixelType,  Dimension> ImageType;

// reader and writers
typedef itk::ImageFileReader< ImageType >  ReaderType;

void gdcmwrite(const char *inputfile, const char *inputdicom, string 
directory);


int main( int argc, char * argv[] )
{
 
    if (argc < 4) {
        std::cerr << argv[0] << USAGE << std::endl;
        return 1;
    } 

    // save output
    cout << "Converting image into dicom in " << argv[2] << endl;
    gdcmwrite(argv[1], argv[2], argv[3]);
 
    return 0;
}


void gdcmwrite(const char *inputfile, const char *inputdicom, string 
directory)
{
    // define read object and set parameters
    ReaderType::Pointer reader = ReaderType::New();
 
    // get input image
    cout << "Loading image " << inputfile << endl;
    reader->SetFileName( inputfile );
    reader->Update(); 
    cout << "Image Loaded." << endl;

    ImageType::Pointer input = reader->GetOutput();
    input->GetPixelContainer()->SetContainerManageMemory( true );
    PixelType* imageData = input->GetPixelContainer()->GetImportPointer();

    itksys::SystemTools::ConvertToUnixSlashes( directory );
    if (directory[directory.size()-1] != '/')
        directory += '/';

    int sizex = input->GetLargestPossibleRegion().GetSize()[0];
    int sizey = input->GetLargestPossibleRegion().GetSize()[1];
    int sizez = input->GetLargestPossibleRegion().GetSize()[2];
    float spacing[3] = 
{input->GetSpacing()[0],input->GetSpacing()[1],input->GetSpacing()[2]};
    float orig[3]    = {input->GetOrigin()[0], input->GetOrigin()[1], 
input->GetOrigin()[2]};
    int sliceSize = sizex*sizey*sizeof(PixelType);

    gdcm::Header *h1 = new gdcm::Header(inputdicom);
    if (!h1->IsReadable()) {
        std::cerr << "Sorry, not a Readable DICOM / ACR File" <<std::endl;
        return;
    }
    else {
        h1->ReplaceOrCreateByNumber( "TestPatient", 0x0010, 0x0010);// 
patientName
        h1->ReplaceOrCreateByNumber( "Nobody", 0x0032, 0x1032);// refering 
physician
        h1->ReplaceOrCreateByNumber( "1", 0x0028, 0x0002);// Samples per 
pixel 1 or 3
        h1->ReplaceOrCreateByNumber( "MONOCHROME2 ", 0x0028, 0x0004);// 
photochromatic interpretation
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%d", 1), 0x0028, 
0x0008);// nbFrames
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%d", sizey), 
0x0028, 0x0010);// nbRows
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%d", sizex), 
0x0028, 0x0011);// nbCols
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%f\\%f", 
spacing[0],spacing[1]), 0x0028, 0x0030);// pixelSpacing
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%f", spacing[2]), 
0x0018, 0x0050);// slice Thickness
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%f", spacing[2]), 
0x0018, 0x0088);// space between slices
        h1->ReplaceOrCreateByNumber( "16", 0x0028, 0x0100);// 
BitsAllocated 8 or 16
        h1->ReplaceOrCreateByNumber( "12", 0x0028, 0x0101);// BitsStored  
8 or 12
        h1->ReplaceOrCreateByNumber( "11", 0x0028, 0x0102);// HighBit  7 
or 11
        h1->ReplaceOrCreateByNumber( "1", 0x0028, 0x0103);// Pixel 
Representation 0(unsigned) or 1(signed)
        h1->ReplaceOrCreateByNumber( "0", 0x0028, 0x1052);// Rescale 
Intercept
        h1->ReplaceOrCreateByNumber( "1", 0x0028, 0x1053);// Rescale Slope
        h1->SetImageDataSize(sliceSize);
    }
 
    gdcm::File  *f1 = new gdcm::File(h1);
 
    for (int z=0; z<sizez; z++) {
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%g\\%g\\%g",
 orig[0],orig[1],orig[2]+z*spacing[0]), 0x0020, 0x0032);// im pos
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%f",
 orig[2]+z*spacing[0]), 0x0020, 0x1041);// slice location
        h1->ReplaceOrCreateByNumber( gdcm::Util::Format("%d",
                                                        z+1), 0x0020, 
0x0013);// instance

        // f1->GetImageData();
        uint8_t *myData = (uint8_t *) malloc(sliceSize);
        memcpy(myData,imageData+z*sizex*sizey,sliceSize);
        // h1->Print();

        f1->SetImageData( myData, sliceSize);
        h1->SetImageDataSize( sliceSize );

        std::string s10 = f1->GetHeader()->GetEntryByNumber(0x7fe0, 
0x0010);
        std::cout << "lgr 7fe0, 0010 " << s10 << std::endl;

 
        char filename[512];
        sprintf (filename, "%s/IMAGE_%05d.dcm", directory.c_str(), z);
        std::cout << "Writing file " << filename;
        f1->WriteDcmExplVR(filename);
        std::cout << " OK" << std::endl;
        cout << "DataSize: " << f1->GetImageDataSize() << endl;
    }
    // delete f1; // this crashes the program.
}











Mathieu Malaterre <mathieu.malaterre at kitware.com>
27/10/2004 23:06

 
        To:     Jean-Michel Rouet/SUR/RESEARCH/PHILIPS at PHILIPS
        cc:     Dcmlib at creatis.insa-lyon.fr
        Subject:        Re: [Dcmlib] converting itk,vtk or any other 3D images into dicom.
        Classification: 




Salut,

                 Il y a un test gdcm/TestChangeHeader.cxx qui devrait 
faire l'affaire.
                 Pour y aller etapes par etapes, je lirai une image dicom 
multiframe 
(y'en a dans gdcmData). Ensuite il faut /sans doute/ changer la taille 
de l'image (0x0028,0x0011). Puis passer un pointeur vers l'image data. 
Ensuite y'aura des problemes liee aux bits stored/hish bits et autre, si 
l'image d'entree est vraiment differente de l'image passer par pointeur.

                 En clair, ce n'est pas simple, mais gdcm est vraiment 
tourne'e "d'abord 
dicom en lecture". Ecriture /from scratch/ c'est encore un peu 
experimental. gdcm n'a pas de notion de tag necessaire lors de 
l'ecriture. Donc si l'utilisateur oubli un tag essentiel l'image a de 
grande chance de ne pas pouvoir etre relue.

                 En tout cas c'est un tres bon exercice, je vais voir si 
je peux ajouter 
un test/exemple dans gdcm.

HTH
Mathieu

jean-michel.rouet at philips.com wrote:
> 
> Bonjour tout le monde,
> 
> j'ai regardé un peu sur les archives, mais comme il n'y a pas de 
> "search" sur la page http://www.creatis.insa-lyon.fr/Public/Gdcm/, je 
> n'ai rien trouvé!
> 
> Je cherche a sauver en format dicom des images 3D (lues a partir de .vtk 

> ou autre).
> Est-ce que qqun peut m'expliquer un peu comment utiliser gdcm pour faire 

> ca ?
> Mais tentatives ont toutes echoué.
> 
> JM
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Dcmlib mailing list
> Dcmlib at creatis.insa-lyon.fr
> http://www.creatis.insa-lyon.fr/mailman/listinfo/dcmlib










More information about the Dcmlib mailing list