DICOM-Image lesen (evt Framework)



  • Leider habe ich hier eine andere Toolchain (g++).
    Aber Deinen Code bekomme ich zum laufen.

    #include <iostream>
    
    #include "dcmtk/dcmdata/dcfilefo.h"
    #include "dcmtk/dcmdata/dctagkey.h"
    #include "dcmtk/dcmdata/dcdeftag.h"
    #include "dcmtk/ofstd/ofcond.h"
    #include "dcmtk/ofstd/ofstring.h"
    
    using namespace std;
    
    int main() {
      const char* file = "/tmp/Case22 [Case22]/"
        "20071030 021043 [ - MAMMOGRAM DIGITAL DX BILAT]/Series 71100000 [MG - L CC]/"
        "1.3.6.1.4.1.5962.99.1.2280943358.716200484.1363785608958.480.0.dcm";
      DcmFileFormat fileformat;
      OFCondition status = fileformat.loadFile(file);
      if (status.good())
        {
          OFString patientName;
          if (fileformat.getDataset()->findAndGetOFString(DCM_PatientName, patientName).good())
    	{
    	  cout << "Patient's Name: " << patientName << endl;
    	} else
            cerr << "Error: cannot access Patient's Name!" << endl;
        } else
        cerr << "Error: cannot read DICOM file (" << status.text() << ")" << endl;
    }
    
    g++ -std=c++11 -Wall -pedantic -g -otest test.cc -I/tmp/dcmtk/include/  -L/tmp/dcmtk/lib/ -lz -ldcmdata -loflog -lofstd -lpthread
    

    Mit diesen Mammo Bildern (131MB!), kommt da (wenig überraschend):

    Patient's Name: Case22
    

    Zum Thema <iostream.h> steht was unter "Known limitations of DCMTK on the Windows platform." in der Dokumentation.

    Bonne chance!



  • Dann bin ich schonmal beruhigt, dass es an meiner Unfähigkeit liegt 😉

    Ich probier mal nen bisl rum mit der Info in der doku und berichte.

    EDIT: Ich seh grad, dass die Einstellungen in der osconfig.h schon so vorgenommen sind, dass es auf die neue Schreibweise passt. 😞

    EDIT2: Mir ist gerade bei der Analyse deines Codes aufgefallen, dass du lediglich /tmp/dcmtk/includes/ als zusätzliche include-Pfade an deinen Compiler übergibst.

    Wenn ich DCMTK builde habe ich allerdings einen dcmtk-Orderner der Unterordner wie z.B.
    -dcmdata
    -dcmimage
    -dcmimgle
    -dcmjpeg
    -...
    enthält.
    und jeder dieser Unterordner hat eigenen "include" ordner.

    Hast du dir die selbst zusammen kopiert, oder hab ich was falsch gemacht?

    Zur Sicherheit hier nochmal mein vorgehen.

    1: ftp://dicom.offis.de/pub/dicom/offis/software/dcmtk/dcmtk360/dcmtk-3.6.0.tar.gz
    Herunterladen

    2: entpacken

    3: CMake Starten
    - input folder dcmtk-3.6.0
    - output folder dcmtk-bin

    Configure mit dem VS2012 Compiler (VS11)

    EXE (dcmtk-exe) und LIB(dcmtk-lib) part angeben - ansonsten hab ich an den Einstellungen nichts geändert

    4: Erneut configure drücken damit die Einstellungen gespeichert werden
    5: Generate

    6: Ins verzeichnis dcmtk-bin gehen
    7: *.sln mit VS2012 Öffnen und Projekt neu Erstellen (müsste dem make all entsprechen - dcmtk-lib und dcmtk-exe werden erstellt)

    8: Projekt Anlegen
    9: dcmtk-3.6.0 alle nötigen include Pfade setzten
    10: Lib such-Pfad auf dcmtk-lib erweitern
    11: Libs dem projekt hinzufügen

    Los Proggen glücklich sein, dass Nichts funktioniert 😃

    Gruß



  • Oha!
    Ich sollte vielleicht noch sagen, dass ich den "neuesten Snapshot" (dcmtk-3.6.1_20131114.tar.gz) benutzt habe.



  • Oh du hast ja schon wieder was gepostet 😃

    Ich hab meinen vorherigen Beitrag editiert, ich zitiere es eben nochmal.

    Wäre nett wenn du mal drüber schauen könntest, ob ich mir nen groben schnitzer geleistet hab.

    JangoK schrieb:

    EDIT2: Mir ist gerade bei der Analyse deines Codes aufgefallen, dass du lediglich /tmp/dcmtk/includes/ als zusätzliche include-Pfade an deinen Compiler übergibst.

    Wenn ich DCMTK builde habe ich allerdings einen dcmtk-Orderner der Unterordner wie z.B.
    -dcmdata
    -dcmimage
    -dcmimgle
    -dcmjpeg
    -...
    enthält.
    und jeder dieser Unterordner hat eigenen "include" ordner.

    Hast du dir die selbst zusammen kopiert, oder hab ich was falsch gemacht?

    Zur Sicherheit hier nochmal mein vorgehen.

    1: ftp://dicom.offis.de/pub/dicom/offis/software/dcmtk/dcmtk360/dcmtk-3.6.0.tar.gz
    Herunterladen

    2: entpacken

    3: CMake Starten
    - input folder dcmtk-3.6.0
    - output folder dcmtk-bin

    Configure mit dem VS2012 Compiler (VS11)

    EXE (dcmtk-exe) und LIB(dcmtk-lib) part angeben - ansonsten hab ich an den Einstellungen nichts geändert

    4: Erneut configure drücken damit die Einstellungen gespeichert werden
    5: Generate

    6: Ins verzeichnis dcmtk-bin gehen
    7: *.sln mit VS2012 Öffnen und Projekt neu Erstellen (müsste dem make all entsprechen - dcmtk-lib und dcmtk-exe werden erstellt)

    8: Projekt Anlegen
    9: dcmtk-3.6.0 alle nötigen include Pfade setzten
    10: Lib such-Pfad auf dcmtk-lib erweitern
    11: Libs dem projekt hinzufügen

    Los Proggen glücklich sein, dass Nichts funktioniert 😃

    Habe mir jetzt auch mal eben den 3.6.1 herunter geladen - wenn du keinen groben schnitzer findest werde ich die o.g. anweisungen nochmal mit dem durchgehen

    Gruß



  • Wie gesagt: ich bin hier mit Linux und Gedöns unterwegs. Von daher kann ich nicht viel beisteuern.
    Was Du beschreibst scheint aber "ziemlich genau"(TM) dem zu entsprechen, was in der Anleitung steht. 🙂



  • Hab jetzt mal alles mit Version 3.6.1 probiert und die selben libs gelinkt wie du.

    Außerdem habe ich alle includes in einen ordner rein Kopiert, damit das mit den Such Pfaden für den Compiler einfacher klappt.

    Kriege nun folgende Fehlermeldung

    1>------ Erstellen gestartet: Projekt: DCMTKTest, Konfiguration: Debug Win32 ------
    1>  main.cpp
    1>c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\oflog\tracelog.h(59): error C2678: Binärer Operator '+': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'const wchar_t [8]' akzeptiert (oder keine geeignete Konvertierung möglich)
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(867): kann 'OFString operator +(const OFString &,const OFString &)' sein
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(874): oder "OFString operator +(const char *,const OFString &)"
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(881): oder "OFString operator +(char,const OFString &)"
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(888): oder "OFString operator +(const OFString &,const char *)"
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(895): oder "OFString operator +(const OFString &,char)"
    1>          bei Anpassung der Argumentliste '(const wchar_t [8], dcmtk::log4cplus::tstring)'
    1>c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\oflog\tracelog.h(64): error C2678: Binärer Operator '+': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'const wchar_t [8]' akzeptiert (oder keine geeignete Konvertierung möglich)
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(867): kann 'OFString operator +(const OFString &,const OFString &)' sein
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(874): oder "OFString operator +(const char *,const OFString &)"
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(881): oder "OFString operator +(char,const OFString &)"
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(888): oder "OFString operator +(const OFString &,const char *)"
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\ofstd\ofstring.h(895): oder "OFString operator +(const OFString &,char)"
    1>          bei Anpassung der Argumentliste '(const wchar_t [8], dcmtk::log4cplus::tstring)'
    1>c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\oflog\logmacro.h(107): error C2665: "dcmtk::log4cplus::Logger::getInstance": Durch keine der 2 Überladungen konnten alle Argumenttypen konvertiert werden.
    1>          c:\users\kleinmanns\documents\visual studio 2012\projects\dcmtk\include\dcmtk\oflog\logger.h(112): kann 'dcmtk::log4cplus::Logger dcmtk::log4cplus::Logger::getInstance(const dcmtk::log4cplus::tstring &)' sein
    1>          bei Anpassung der Argumentliste '(const dcmtk::log4cplus::tchar *)'
    ========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========
    

    Diese lässt sich beheben, wenn ich den Zeichensatz nicht mehr auf UNICODE stehen habe.

    Dann kommt aber natürlich direkt eine neue Fehlermeldung 😉

    1>------ Erstellen gestartet: Projekt: DCMTKTest, Konfiguration: Debug Win32 ------
    1>  main.cpp
    1>dcmdata.lib(dcuid.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_Netbios@4" in Funktion ""unsigned char * __cdecl getMACAddress(unsigned char * const)" (?getMACAddress@@YAPAEQAE@Z)".
    1>dcmdata.lib(dcuid.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_gethostbyname@4" in Funktion ""long __cdecl gethostid(void)" (?gethostid@@YAJXZ)".
    1>ofstd.lib(ofstd.obj) : error LNK2001: Nicht aufgelöstes externes Symbol "_gethostbyname@4".
    1>dcmdata.lib(dcuid.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_gethostname@8" in Funktion ""long __cdecl gethostid(void)" (?gethostid@@YAJXZ)".
    1>dcmdata.lib(dcuid.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_WSAStartup@8" in Funktion ""long __cdecl gethostid(void)" (?gethostid@@YAJXZ)".
    1>dcmdata.lib(dcuid.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_WSACleanup@0" in Funktion ""long __cdecl gethostid(void)" (?gethostid@@YAJXZ)".
    1>oflog.lib(oflog.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__WSAStartup@8" in Funktion ""void __cdecl OFLog_init(void)" (?OFLog_init@@YAXXZ)".
    1>oflog.lib(winsock.obj) : error LNK2001: Nicht aufgelöstes externes Symbol "__imp__WSAStartup@8".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__accept@12" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::acceptSocket(int,enum dcmtk::log4cplus::helpers::SocketState &)" (?acceptSocket@helpers@log4cplus@dcmtk@@YAHHAAW4SocketState@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__bind@12" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::openSocket(unsigned short,enum dcmtk::log4cplus::helpers::SocketState &)" (?openSocket@helpers@log4cplus@dcmtk@@YAHGAAW4SocketState@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__closesocket@4" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::closeSocket(int)" (?closeSocket@helpers@log4cplus@dcmtk@@YAHH@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__connect@12" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::connectSocket(class OFString const &,unsigned short,bool,enum dcmtk::log4cplus::helpers::SocketState &)" (?connectSocket@helpers@log4cplus@dcmtk@@YAHABVOFString@@G_NAAW4SocketState@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__htonl@4" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::openSocket(unsigned short,enum dcmtk::log4cplus::helpers::SocketState &)" (?openSocket@helpers@log4cplus@dcmtk@@YAHGAAW4SocketState@123@@Z)".
    1>oflog.lib(sockbuff.obj) : error LNK2001: Nicht aufgelöstes externes Symbol "__imp__htonl@4".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__htons@4" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::connectSocket(class OFString const &,unsigned short,bool,enum dcmtk::log4cplus::helpers::SocketState &)" (?connectSocket@helpers@log4cplus@dcmtk@@YAHABVOFString@@G_NAAW4SocketState@123@@Z)".
    1>oflog.lib(sockbuff.obj) : error LNK2001: Nicht aufgelöstes externes Symbol "__imp__htons@4".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__listen@8" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::openSocket(unsigned short,enum dcmtk::log4cplus::helpers::SocketState &)" (?openSocket@helpers@log4cplus@dcmtk@@YAHGAAW4SocketState@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__recv@16" in Funktion ""long __cdecl dcmtk::log4cplus::helpers::read(int,class dcmtk::log4cplus::helpers::SocketBuffer &)" (?read@helpers@log4cplus@dcmtk@@YAJHAAVSocketBuffer@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__send@16" in Funktion ""long __cdecl dcmtk::log4cplus::helpers::write(int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?write@helpers@log4cplus@dcmtk@@YAJHABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__setsockopt@20" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::setTCPNoDelay(int,bool)" (?setTCPNoDelay@helpers@log4cplus@dcmtk@@YAHH_N@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__gethostbyname@4" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::connectSocket(class OFString const &,unsigned short,bool,enum dcmtk::log4cplus::helpers::SocketState &)" (?connectSocket@helpers@log4cplus@dcmtk@@YAHABVOFString@@G_NAAW4SocketState@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__gethostname@8" in Funktion ""class OFString __cdecl dcmtk::log4cplus::helpers::getHostname(bool)" (?getHostname@helpers@log4cplus@dcmtk@@YA?AVOFString@@_N@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__WSACleanup@0" in Funktion ""public: __thiscall `anonymous namespace'::WinSockInitializer::~WinSockInitializer(void)" (??1WinSockInitializer@?A0x0e240de9@@QAE@XZ)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__WSAGetLastError@0" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::connectSocket(class OFString const &,unsigned short,bool,enum dcmtk::log4cplus::helpers::SocketState &)" (?connectSocket@helpers@log4cplus@dcmtk@@YAHABVOFString@@G_NAAW4SocketState@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__WSASocketA@24" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::connectSocket(class OFString const &,unsigned short,bool,enum dcmtk::log4cplus::helpers::SocketState &)" (?connectSocket@helpers@log4cplus@dcmtk@@YAHABVOFString@@G_NAAW4SocketState@123@@Z)".
    1>oflog.lib(winsock.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__WSAStringToAddressA@20" in Funktion ""int __cdecl dcmtk::log4cplus::helpers::connectSocket(class OFString const &,unsigned short,bool,enum dcmtk::log4cplus::helpers::SocketState &)" (?connectSocket@helpers@log4cplus@dcmtk@@YAHABVOFString@@G_NAAW4SocketState@123@@Z)".
    1>oflog.lib(sockbuff.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__ntohl@4" in Funktion ""public: unsigned int __thiscall dcmtk::log4cplus::helpers::SocketBuffer::readInt(void)" (?readInt@SocketBuffer@helpers@log4cplus@dcmtk@@QAEIXZ)".
    1>oflog.lib(sockbuff.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__ntohs@4" in Funktion ""public: unsigned short __thiscall dcmtk::log4cplus::helpers::SocketBuffer::readShort(void)" (?readShort@SocketBuffer@helpers@log4cplus@dcmtk@@QAEGXZ)".
    1>ofstd.lib(ofstd.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_gethostbyaddr@12" in Funktion ""public: static class OFStandard::OFHostent __cdecl OFStandard::getHostByAddr(char const *,int,int)" (?getHostByAddr@OFStandard@@SA?AVOFHostent@1@PBDHH@Z)".
    1>C:\Users\Kleinmanns\documents\visual studio 2012\Projects\DCMTKTest\Debug\DCMTKTest.exe : fatal error LNK1120: 25 nicht aufgelöste Externe
    ========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========
    

    (zlib ist eingebunden)

    Nachdem ich zu der zlib_d.lib noch folgende libs gebunden hab, hats geklappt

    zlib_o.lib;netapi32.lib;wsock32.lib;WS2_32.Lib

    Kann aus meinem DICOM zwar kein patienten namen ziehen.
    Allerdings ist mein test-DICOM auch anonymisiert, also sollte das passen

    Gott wasn stress mit dem **** ^^

    Gruß



  • Ja dann: Viel Erfolg für die Arbeit! 🙂



  • Also das DCMTK-Framework läuft jetzt soweit und ich kann damit arbeiten,

    allerdings verzweifle ich immernoch am DICOM-Format 😕 😕

    Ich habe ein DICOM-Bild eingelesen und kann auch ganz gut auf alle Header-Informationen zugreifen, die abgespeichert sind.

    Ich würde allerdings gerne auf die einzelnen Farbwerte jedes Pixels zugreifen.

    Anhand von

    data->findAndGetOFString(DCM_Columns, width);
    data->findAndGetOFString(DCM_Rows, height);
    

    kann ich ermitteln, dass mein Bild 1024x1024 Pixel groß ist.

    Ich würde also 1.048.576 Grauwerte erwarten (1024*1024 eben)
    wenn ich in das Bild rein schaue habe ich effektiv 691.290 Grauwerte.

    Also fehlen mir grob 300.000 Grauwerte.
    Daraus lässt sich leicht schließen, dass meine Bilddaten Komprimiert sind.

    Nach ein wenig googeln habe ich folgenden Code gefunden/ausprobiert der angeblich meine Daten dekomprimieren sollte.

    ...
    
    // Der Code ist bereits aus meinem Projekt kopiert, original Code hier zu finden
    // http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data
    
    	DcmFileFormat dfile;
    	if(dfile.loadFile(filename.c_str()).bad())
    		return 1;
    
    	DcmDataset *data = dfile.getDataset();
    
    	DcmPixelData *pixelData;
    	DcmElement *dcmElement;
    	data->findAndGetElement(DCM_PixelData, dcmElement);
    	pixelData = OFstatic_cast(DcmPixelData*, dcmElement);
    
    	E_TransferSyntax transferSyntax = EXS_Unknown;
    	const DcmRepresentationParameter *repPara = NULL;
    	pixelData->getOriginalRepresentationKey(transferSyntax, repPara);
    
    	DcmPixelSequence *pixelSequence = NULL;
    	if(pixelData->getEncapsulatedRepresentation(transferSyntax, repPara, pixelSequence).good() && pixelSequence != NULL) {
    		DcmPixelItem *i1;
    		pixelSequence->getItem(i1, 0);
    		DcmPixelItem *i2;
    		pixelSequence->getItem(i2, 1);
    
    		i1->print(cout);
    		i2->print(cout);
    	}
    ...
    

    Ausgabe:

    (fffe,e000) pi 00\00\00\00     #    4  ,1 Item
    (fffe,e000) pi (not loaded)    # 691290,1 Item
    

    es scheitert am angeblich ^^

    Ich habe leider keinerlei Informationen darüber wie die Daten komprimiert sind
    und auch im DICOM-Header habe ich nichts gefunden,
    falls es hilft kann ich Euch auch ein Beispiel-File zu verfügung stellen, meine Projekt-Daten sind ohnehin Anonymisiert.

    Kann mir jemand helfen?
    Ich bin echt am verzweifeln 😞

    EDIT: Link zum DICOM-Image
    https://www.dropbox.com/s/aoxmm8ukyitwa6f/00063

    Gruß



  • Oh man: ich merke ich habe seit Urzeiten nix mehr mit DICOM gemacht. 🙂
    Seinerzeit fand ich allerdings dcmdump aus dem dcmtk immer praktisch.
    Evtl. hilft Dir das ja schon.



  • Falls jemand vor dem selben Problem steht.

    dieser Code funktioniert für JPG-Compressed Images mit DCMTK

    #ifndef DICOMREADER_HPP
    #define DICOMREADER_HPP
    
    #include <string>
    #include "dcmtk/dcmdata/dctk.h"
    
    using namespace std;
    
    class DicomReader {
    protected:
    	int width;
    	int height;
    	unsigned char *pixelData;
    	DcmDataset *data;
    	DcmFileFormat *dcmFileFormat;
    
    	void calcWidth();
    	void calcHeight();
    	void calcPixelData();
    
    public:
    	DicomReader();
    	DicomReader(string filename);
    	void readFile(string filename);
    
    	int getWidth();
    	int getHeight();
    	unsigned char *getPixelData();
    
    	~DicomReader();
    };
    
    #endif
    
    #include "DicomReader.hpp"
    
    #include "dcmtk/config/osconfig.h" 
    #include "dcmtk/dcmdata/dcfilefo.h" 
    #include "dcmtk/dcmdata/dctagkey.h" 
    #include "dcmtk/dcmdata/dcdeftag.h" 
    #include "dcmtk/ofstd/ofcond.h" 
    #include "dcmtk/ofstd/ofstring.h" 
    #include "dcmtk/dcmjpeg/djdecode.h"
    
    DicomReader::DicomReader() {
    	this->dcmFileFormat = new DcmFileFormat();
    	this->data = NULL;
    	this->pixelData = NULL;
    	this->width = 0;
    	this->height = 0;
    }
    DicomReader::DicomReader(string filename) {
    	this->dcmFileFormat = new DcmFileFormat();
    	this->readFile(filename);
    	this->pixelData = NULL;
    	this->width = 0;
    	this->height = 0;
    }
    
    void DicomReader::readFile(string filename) {
    	if(this->dcmFileFormat->loadFile(filename.c_str()).bad())
    		cerr << "Could not load File" << endl;
    	else
    		this->data = this->dcmFileFormat->getDataset();
    }
    
    void DicomReader::calcPixelData() {
    	Uint16 tmpWidth;
    	Uint16 tmpHeight;
    
    	DJDecoderRegistration::registerCodecs();
    
    	this->data->findAndGetUint16(DCM_Rows, tmpHeight);
    	this->data->findAndGetUint16(DCM_Columns, tmpWidth);
    
    	// decompress
    	this->data->chooseRepresentation(EXS_LittleEndianExplicit, NULL);
    
    	if (data->canWriteXfer(EXS_LittleEndianExplicit)) {
    		const Uint16 *pixelData16;
    		this->pixelData = new unsigned char [tmpHeight*tmpWidth];
    
    		this->data->findAndGetUint16Array(DCM_PixelData, pixelData16);
    		// 16Bit (12 used) Greyscale to 8Bit Greyscale
    		for(int i = 0; i < tmpHeight*tmpWidth; i++) {
    			this->pixelData[i] = pixelData16[i] / 8;
    		}
    		this->width = (int)tmpWidth;
    		this->height = (int)tmpHeight;
    	}
    	DJDecoderRegistration::cleanup();
    }
    unsigned char *DicomReader::getPixelData() {
    	if(this->pixelData == NULL)
    		this->calcPixelData();
    	return this->pixelData;
    }
    
    void DicomReader::calcWidth() {
    	Uint16 tmpWidth;
    	this->data->findAndGetUint16(DCM_Columns, tmpWidth);
    	this->width = (int)tmpWidth;
    }
    int DicomReader::getWidth() {
    	if(this->width == 0)
    		this->calcWidth();
    	return this->width;
    }
    void DicomReader::calcHeight() {
    	Uint16 tmpHeight;
    	this->data->findAndGetUint16(DCM_Rows, tmpHeight);
    	this->height = (int)tmpHeight;
    }
    int DicomReader::getHeight() {
    	if(this->height == 0)
    		this->calcHeight();
    	return this->height;
    }
    
    DicomReader::~DicomReader() {
    	delete this->dcmFileFormat;
    	// delete this->data; Wird im destruktor von dcmFileFormat schon gekillt
    	delete[] this->pixelData;
    }
    

Anmelden zum Antworten