[Dcmlib] [Fwd: [Insight-developers] anonymize DICOM files]

Jean-Pierre Roux jpr at creatis.insa-lyon.fr
Fri Feb 4 17:43:03 CET 2005


Mathieu Malaterre wrote:

> Ok , j'ai citer moi meme cette methode. Le probleme c'est que gdcm va 
> lire *ET* interpreter l'image avant de la reecrire.


Desole !
Je venais de relire ta reponse , jusqu'au bout cette fois...

J'ai vu les Theralyssiens, a midi.
La manip serait de passer un ensenmble de -list, vector, ou autre 
chose-  tuples (group, elem, newValue) a une methode.
Pour chaque element, on a son offset  (sa position a partir du debut du 
fichier), on fait des fseek, fwrite avec la nouvelle valeur si elle 
tient, ou des espaces sur la bonne longueur.
En sachant qu'on recrit sur l'image (l'utilisateur n'a qu'a bosser sur 
une copie)

JP

>
> Donc dans le cas ou une image n'est pas lisible par gdcm (jpeg2000 par 
> ex), ou est dans les choux. Je cherche quelque chose qui pourrait 
> preserver l'image DICOM et qui ne changerait que l'entete... A mon 
> avis c'est chaud a faire.
>
> Ext-ce que ma requete est plus clair ?
>
> Merci,
> Mathieu
> Le cas de figure c'est quelqu'un aui n'arrive pas a lire une image 
> DICOM et qui voudrait l'envoyer a l'equipe gdcm, mais il aurait besoin 
> de l'anonymiser avant !
>
> Jean-Pierre Roux wrote:
>
>> Mathieu Malaterre wrote:
>>
>>> Je fais suivre un example de la ML ITK.
>>>
>>> Il lui manquait la ligne super importante dans gdcm 0.6:
>>>
>>> gdcm::File f(&h);
>>> f.GetImageData(); //super important
>>> f.WriteDcmExplVR(OutputFilename);
>>>
>>> Sinon c'est realisable un vrai 'anonymiser' ? C'est a dire ne 
>>> modifier que l'entete sans essayer de lire/analyser l'image data ? 
>>> (=a la hexedit).
>>
>>
>>
>>
>> Il y a la methode gdcm::File::AnonymizeFile()
>>
>> /**
>> * \brief anonymize a File (removes Patient's personal info)
>> * (read the code to see which ones ...)
>> */
>> bool File::AnonymizeFile()
>> {
>> // If exist, replace by spaces
>> SetValEntry (" ",0x0010, 0x2154); // Telephone
>> SetValEntry (" ",0x0010, 0x1040); // Adress
>> SetValEntry (" ",0x0010, 0x0020); // Patient ID
>>
>> DocEntry* patientNameHE = GetDocEntry (0x0010, 0x0010);
>>
>> if ( patientNameHE ) // we replace it by Study Instance UID (why not)
>> {
>> std::string studyInstanceUID = GetEntryValue (0x0020, 0x000d);
>> if ( studyInstanceUID != GDCM_UNFOUND )
>> {
>> InsertValEntry(studyInstanceUID, 0x0010, 0x0010);
>> }
>> else
>> {
>> InsertValEntry("anonymised", 0x0010, 0x0010);
>> }
>> }
>>
>> // Just for fun :-(
>> // (if any) remove or replace all the stuff that contains a Date
>>
>> //0008 0012 DA ID Instance Creation Date
>> //0008 0020 DA ID Study Date
>> //0008 0021 DA ID Series Date
>> //0008 0022 DA ID Acquisition Date
>> //0008 0023 DA ID Content Date
>> //0008 0024 DA ID Overlay Date
>> //0008 0025 DA ID Curve Date
>> //0008 002a DT ID Acquisition Datetime
>> //0018 9074 DT ACQ Frame Acquisition Datetime
>> //0018 9151 DT ACQ Frame Reference Datetime
>> //0018 a002 DT ACQ Contribution Date Time
>> //0020 3403 SH REL Modified Image Date (RET)
>> //0032 0032 DA SDY Study Verified Date
>> //0032 0034 DA SDY Study Read Date
>> //0032 1000 DA SDY Scheduled Study Start Date
>> //0032 1010 DA SDY Scheduled Study Stop Date
>> //0032 1040 DA SDY Study Arrival Date
>> //0032 1050 DA SDY Study Completion Date
>> //0038 001a DA VIS Scheduled Admission Date
>> //0038 001c DA VIS Scheduled Discharge Date
>> //0038 0020 DA VIS Admitting Date
>> //0038 0030 DA VIS Discharge Date
>> //0040 0002 DA PRC Scheduled Procedure Step Start Date
>> //0040 0004 DA PRC Scheduled Procedure Step End Date
>> //0040 0244 DA PRC Performed Procedure Step Start Date
>> //0040 0250 DA PRC Performed Procedure Step End Date
>> //0040 2004 DA PRC Issue Date of Imaging Service Request
>> //0040 4005 DT PRC Scheduled Procedure Step Start Date and Time
>> //0040 4011 DT PRC Expected Completion Date and Time
>> //0040 a030 DT PRC Verification Date Time
>> //0040 a032 DT PRC Observation Date Time
>> //0040 a120 DT PRC DateTime
>> //0040 a121 DA PRC Date
>> //0040 a13a DT PRC Referenced Datetime
>> //0070 0082 DA ??? Presentation Creation Date
>> //0100 0420 DT ??? SOP Autorization Date and Time
>> //0400 0105 DT ??? Digital Signature DateTime
>> //2100 0040 DA PJ Creation Date
>> //3006 0008 DA SSET Structure Set Date
>> //3008 0024 DA ??? Treatment Control Point Date
>> //3008 0054 DA ??? First Treatment Date
>> //3008 0056 DA ??? Most Recent Treatment Date
>> //3008 0162 DA ??? Safe Position Exit Date
>> //3008 0166 DA ??? Safe Position Return Date
>> //3008 0250 DA ??? Treatment Date
>> //300a 0006 DA RT RT Plan Date
>> //300a 022c DA RT Air Kerma Rate Reference Date
>> //300e 0004 DA RT Review Date
>>
>> return true;
>> }
>>
>>>
>>> Mathieu
>>>
>>>
>>> -------- Original Message --------
>>> Subject: [Insight-developers] anonymize DICOM files
>>> Date: Thu, 03 Feb 2005 17:26:17 -0600
>>> From: Kent Williams <norman-k-williams at uiowa.edu>
>>> To: insight-developers at itk.org
>>>
>>> I have several DICOM data sets that for one reason or another are not
>>> working properly with the gdcm Dicom reader. The problems we're having
>>> aren't a big deal -- and I can deal with it off the list with the GDCM
>>> guy -- but I need to anonymize the datasets before sending them 
>>> offsite.
>>>
>>> My idea was to write a simple app that anonymizes the header and 
>>> dumps a
>>> new file out. gdcm::Header has a function called 'AnonymizeHeader' that
>>> I copied to blank out the problem fields, but it's not clear to me how
>>> to read in the whole dicom slice and write it back out along with the
>>> pixel data -- using GDCM.
>>>
>>> What's happening is that it appears the header is getting written 
>>> out OK
>>> but the pixel data is not.
>>>
>>> Below is the program I wrote -- clearly I'm missing the 'read in the
>>> data from the input data, attach it to the output file stage.'
>>>
>>> I would have used an anonymizer someone else wrote -- if there was 
>>> one I
>>> could trust, that was free, and didn't have a stupid user interface!
>>> Google didn't find anything like that!
>>>
>>>
>>> #include "gdcm.h"
>>> #include "unistd.h"
>>>
>>> int
>>> main(int argc, char **argv)
>>> {
>>> char *inputfilename(0),
>>> *outputfilename(0);
>>> int c;
>>> bool quitopt = false;
>>> while(!quitopt && (c = getopt(argc,argv,"i:o:")) != -1)
>>> {
>>> switch(c)
>>> {
>>> case 'i':
>>> inputfilename = optarg;
>>> break;
>>> case 'o':
>>> outputfilename = optarg;
>>> break;
>>> default:
>>> quitopt = true;
>>> break;
>>> }
>>> }
>>> if(inputfilename == 0)
>>> {
>>> std::cerr << "No input file given" << std::endl;
>>> exit(-1);
>>> }
>>> if(outputfilename == 0)
>>> {
>>> std::cerr << "No output file given" << std::endl;
>>> exit(-1);
>>> }
>>> std::string InputFilename(inputfilename),
>>> OutputFilename(outputfilename);
>>>
>>> gdcm::Header h(InputFilename);
>>> if(!h.IsReadable())
>>> {
>>> std::cerr << "Can't open input file " << inputfilename << std::endl;
>>> exit(-1);
>>> }
>>> // If exist, replace by spaces
>>> h.SetEntryByNumber (" ",0x0010, 0x2154); // Telephone
>>> h.SetEntryByNumber (" ",0x0010, 0x1040); // Adress
>>> h.SetEntryByNumber (" ",0x0010, 0x0020); // Patient ID
>>>
>>> gdcm::DocEntry* patientNameHE = h.GetDocEntryByNumber (0x0010, 0x0010);
>>>
>>> if ( patientNameHE ) // we replace it with bogus name
>>> {
>>> h.ReplaceOrCreateByNumber("Ernest_T_Bass", 0x0010, 0x0010);
>>> }
>>> gdcm::File f(&h);
>>> f.WriteDcmExplVR(OutputFilename);
>>> }
>>>
>>> _______________________________________________
>>> Insight-developers mailing list
>>> Insight-developers at itk.org
>>> http://www.itk.org/mailman/listinfo/insight-developers
>>>
>>> _______________________________________________
>>> Dcmlib mailing list
>>> Dcmlib at creatis.insa-lyon.fr
>>> http://www.creatis.insa-lyon.fr/mailman/listinfo/dcmlib
>>>
>> _______________________________________________
>> 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