Selaa lähdekoodia

Merge branch 'dicom-thumbnails-for-retrieves'

Marco Nolden 14 vuotta sitten
vanhempi
commit
d583d7fac1

+ 70 - 7
Libs/DICOM/Core/ctkDICOMDatabase.cpp

@@ -36,6 +36,7 @@
 
 // ctkDICOM includes
 #include "ctkDICOMDatabase.h"
+#include "ctkDICOMImage.h"
 
 #include "ctkLogger.h"
 
@@ -51,6 +52,7 @@
 #include <dcmtk/ofstd/ofstring.h>
 #include <dcmtk/ofstd/ofstd.h>        /* for class OFStandard */
 #include <dcmtk/dcmdata/dcddirif.h>   /* for class DicomDirInterface */
+#include <dcmimage.h>
 
 //------------------------------------------------------------------------------
 static ctkLogger logger("org.commontk.dicom.DICOMDatabase" );
@@ -221,22 +223,27 @@ void ctkDICOMDatabase::closeDatabase()
 }
 
 //------------------------------------------------------------------------------
+/*
 void ctkDICOMDatabase::insert ( DcmDataset *dataset ) {
   this->insert ( dataset, QString() );
 }
+*/
 
 //------------------------------------------------------------------------------
-void ctkDICOMDatabase::insert ( DcmDataset *dataset, QString filename ) {
+void ctkDICOMDatabase::insert ( DcmDataset *dataset, bool storeFile, bool createThumbnail ) {
   Q_D(ctkDICOMDatabase);
 
   // Check to see if the file has already been loaded
+  OFString sopInstanceUID ;
+  dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID);
+
   QSqlQuery fileExists ( d->Database );
-  fileExists.prepare("SELECT InsertTimestamp FROM Images WHERE Filename == ?"); 
-  fileExists.bindValue(0,filename);
+  fileExists.prepare("SELECT InsertTimestamp,Filename FROM Images WHERE SOPInstanceUID == ?");
+  fileExists.bindValue(0,QString::fromStdString(sopInstanceUID));
   fileExists.exec();
-  if ( fileExists.next() && QFileInfo(filename).lastModified() < QDateTime::fromString(fileExists.value(0).toString(),Qt::ISODate) )
+  if ( fileExists.next() && QFileInfo(fileExists.value(1).toString()).lastModified() < QDateTime::fromString(fileExists.value(0).toString(),Qt::ISODate) )
     {
-    logger.debug ( "File " + filename + " already added" );
+    logger.debug ( "File " + fileExists.value(1).toString() + " already added" );
     return;
     }
 
@@ -249,7 +256,7 @@ void ctkDICOMDatabase::insert ( DcmDataset *dataset, QString filename ) {
   OFString seriesInstanceUID, seriesDate, seriesTime,
     seriesDescription, bodyPartExamined, frameOfReferenceUID,
     contrastAgent, scanningSequence;
-  OFString instanceNumber, sopInstanceUID ;
+  OFString instanceNumber;
 
   Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0;
 
@@ -258,7 +265,7 @@ void ctkDICOMDatabase::insert ( DcmDataset *dataset, QString filename ) {
   dataset->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID);
   dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID);
   dataset->findAndGetOFString(DCM_PatientID, patientID);
-  dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID);
+
 
   dataset->findAndGetOFString(DCM_PatientsBirthDate, patientsBirthDate);
   dataset->findAndGetOFString(DCM_PatientsBirthTime, patientsBirthTime);
@@ -288,6 +295,24 @@ void ctkDICOMDatabase::insert ( DcmDataset *dataset, QString filename ) {
   dataset->findAndGetSint32(DCM_EchoNumbers, echoNumber);
   dataset->findAndGetSint32(DCM_TemporalPositionIdentifier, temporalPosition);
 
+  // store the file if the database is not in memomry
+  QString filename;
+  if ( storeFile && !this->isInMemory() )
+  {
+    DcmFileFormat* fileformat = new DcmFileFormat ( dataset );
+    filename = databaseDirectory() + "/dicom/" + pathForDataset(dataset);
+    logger.debug ( "Saving file: " + filename );
+    OFCondition status = fileformat->saveFile ( filename.toAscii() );
+    if ( !status.good() )
+      {
+      logger.error ( "Error saving file: " + filename + "\nError is " + status.text() );
+      delete fileformat;
+      return;
+      }
+    delete fileformat;
+  }
+
+
   QSqlQuery check_exists_query(d->Database);
   //The patient UID is a unique number within the database, generated by the sqlite autoincrement
   int patientUID = -1;
@@ -393,8 +418,46 @@ void ctkDICOMDatabase::insert ( DcmDataset *dataset, QString filename ) {
       statement.exec();
       }
     }
+
+  if (createThumbnail)
+  {
+    QString thumbnailBaseDir = databaseDirectory() + "/thumbs/";
+    QString thumbnailFilename = thumbnailBaseDir + "/" + pathForDataset(dataset) + ".png";
+    QFileInfo thumbnailInfo(thumbnailFilename);
+    if ( ! ( thumbnailInfo.exists() && thumbnailInfo.lastModified() < QFileInfo(filename).lastModified() ) )
+    {
+      QString studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str();
+      QDir(thumbnailBaseDir).mkpath(studySeriesDirectory);
+      // TODO: reuse dataset
+      DicomImage dcmtkImage(filename.toAscii());
+      ctkDICOMImage ctkImage(&dcmtkImage);
+      QImage image( ctkImage.getImage(0) );
+      image.scaled(128,128,Qt::KeepAspectRatio).save(thumbnailFilename,"PNG");
+    }
+  }
+
   if (d->DatabaseFileName == ":memory:")
     {
       emit databaseChanged();
     }
 }
+
+bool ctkDICOMDatabase::isInMemory() const
+{
+  Q_D(const ctkDICOMDatabase);
+  return d->DatabaseFileName == ":memory:";
+}
+
+
+QString ctkDICOMDatabase::pathForDataset( DcmDataset *dataset)
+{
+  Q_D(ctkDICOMDatabase);
+
+  OFString studyInstanceUID, seriesInstanceUID, sopInstanceUID;
+  dataset->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID);
+  dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID);
+  dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID);
+
+  return QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str() + "/" + sopInstanceUID.c_str();
+
+}

+ 8 - 2
Libs/DICOM/Core/ctkDICOMDatabase.h

@@ -42,6 +42,7 @@ public:
   const QString lastError() const;
   const QString databaseFilename() const;
   const QString databaseDirectory() const;
+  bool isInMemory() const;
 
   ///
   /// open the SQLite database in @param file. If the file does not
@@ -59,11 +60,16 @@ public:
   /**
    * Will create an entry in the appropriate tables for this dataset.
    */
-  void insert ( DcmDataset* dataset, QString filename );
+  // void insert ( DcmDataset* dataset, QString filename );
   /**
    * Insert into the database if not already exsting.
    */
-  void insert ( DcmDataset *dataset );
+  void insert ( DcmDataset *dataset, bool storeFile = true, bool createThumbnail = true );
+  /***
+    * Helper method: get the path that should be used to store this  image.
+    */
+  QString pathForDataset( DcmDataset *dataset);
+
 signals:
   void databaseChanged();
 protected:

+ 3 - 6
Libs/DICOM/Core/ctkDICOMIndexer.cpp

@@ -371,11 +371,8 @@ void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& database, const QString& di
     }
 
     lastSeriesInstanceUID = seriesInstanceUID;
-    QString studySeriesDirectory;
-    if (createHierarchy || createThumbnails)
-    {
-      studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str();
-    }
+
+    QString studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str();
 
     //----------------------------------
     //Move file to destination directory
@@ -398,7 +395,7 @@ void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& database, const QString& di
     if (createThumbnails)
     {
       QString thumbnailBaseDir =  database.databaseDirectory() + "/thumbs/";
-      QString thumbnailFilename = thumbnailBaseDir + "/" + studySeriesDirectory + "/" + sopInstanceUID.c_str() + ".png";
+      QString thumbnailFilename = thumbnailBaseDir + "/" + database.pathForDataset(dataset) + ".png";
       QFileInfo thumbnailInfo(thumbnailFilename);
       if ( ! ( thumbnailInfo.exists() && thumbnailInfo.lastModified() < QFileInfo(qfilename).lastModified() ) )
       {

+ 1 - 1
Libs/DICOM/Core/ctkDICOMRetrieve.cpp

@@ -219,7 +219,7 @@ void ctkDICOMRetrievePrivate::retrieve ( QString UID, RetrieveType retriveType )
             logger.error ( "Error saving file: " + fi.absoluteFilePath() + " Error is " + status.text() );
             }
 
-          RetrieveDatabase->insert( dataset, fi.absoluteFilePath() );
+          RetrieveDatabase->insert( dataset, true );
           
           delete fileformat;
           }