From cf01d5b519c55669cfa16fb88db023792741c523 Mon Sep 17 00:00:00 2001 From: Shakes XPS 13 Date: Wed, 5 Jul 2017 16:08:13 +1000 Subject: [PATCH] Version 1.01 User Experience Update: Fixed scalarstats not outputing mesh properly. Added specular option to overlay app. Added display of orientation flag in image info. Added method for image orientation in image class Added update of scalar range on refresh for scalar operations. Added DOB and weight to anonymise. Improved progress updates for anonymise DICOMs. Tweaked DICOM anonymise wizard. --- apps/milxModelApp/milxModelApp.cxx | 6 +- apps/milxOverlay/milxOverlay.cpp | 4 + include/milxFile.h | 4 +- include/milxImage.h | 68 +++++++++++ plugin/dicom/milxQtDICOMPlugin.cpp | 188 ++++++++++++++++------------- plugin/dicom/milxQtDICOMPlugin.h | 1 + src/Qt/milxQtImage.cpp | 11 ++ src/Qt/milxQtModel.cpp | 1 + 8 files changed, 195 insertions(+), 88 deletions(-) diff --git a/apps/milxModelApp/milxModelApp.cxx b/apps/milxModelApp/milxModelApp.cxx index 17083b0..96cdcd3 100644 --- a/apps/milxModelApp/milxModelApp.cxx +++ b/apps/milxModelApp/milxModelApp.cxx @@ -113,7 +113,7 @@ int main(int argc, char *argv[]) SwitchArg concatenateArg("", "cat", "Concatenate N surfaces into single mesh with filename provided.", false); SwitchArg colourConcatenateArg("", "colourcat", "Concatenate N surfaces into single mesh with filename provided and colour them.", false); SwitchArg splitArg("", "split", "Split each surface given components.", false); - SwitchArg diffScalarArg("", "scalardiff", "Compute the differences in Scalars.", false); + SwitchArg diffScalarArg("", "scalardiff", "Compute the differences in Scalars to the first mesh in list.", false); SwitchArg statsScalarArg("", "scalarstats", "Compute statistics of scalars (mean, variance etc. per point) output mesh with stats as arrays.", false); SwitchArg removeScalarArg("", "scalarremove", "Remove the scalars.", false); SwitchArg copyScalarArg("", "scalarcopy", "Copy the Scalars from first mesh to all others while removing existing ones.", false); @@ -591,6 +591,8 @@ int main(int argc, char *argv[]) case diffscalars: Model.ScalarDifferenceCollection(collection); + outputRequired = true; + multiOutputRequired = false; break; case diffscalarspairs: @@ -603,6 +605,8 @@ int main(int argc, char *argv[]) case statscalars: Model.ScalarStatisticsCollection(collection); + outputRequired = true; + multiOutputRequired = false; break; case removescalars: diff --git a/apps/milxOverlay/milxOverlay.cpp b/apps/milxOverlay/milxOverlay.cpp index fe3ddf4..ee611d9 100644 --- a/apps/milxOverlay/milxOverlay.cpp +++ b/apps/milxOverlay/milxOverlay.cpp @@ -117,6 +117,7 @@ int main(int argc, char* argv[]) SwitchArg wireframeArg("", "wireframe", "Display initial surface as a wireframe model.", false); SwitchArg wireframesArg("", "wireframes", "Display all surfaces as a wireframe models.", false); SwitchArg humanArg("", "nohuman", "Disable human orientation glyph.", false); + SwitchArg specularArg("", "nospecular", "Disable specular lighting for the rendered view.", false); ///Mandatory UnlabeledMultiArg multinames("surfaces", "Surfaces to overlay", true, "Surfaces"); @@ -184,6 +185,7 @@ int main(int argc, char* argv[]) cmd.add( wireframeArg ); cmd.add( wireframesArg ); cmd.add( humanArg ); + cmd.add( specularArg ); ///Parse the argv array. cmd.parse( argc, argv ); @@ -610,6 +612,8 @@ int main(int argc, char* argv[]) model->loadView(); if(loadViewFileArg.isSet()) model->loadView(loadViewName.c_str()); + if(specularArg.isSet()) + model->disableSpecularDisplay(); //Zoom if(zoomArg.isSet()) { diff --git a/include/milxFile.h b/include/milxFile.h index 3784818..f0da19c 100644 --- a/include/milxFile.h +++ b/include/milxFile.h @@ -990,7 +990,7 @@ itk::SmartPointer File::ReadImageUsingITK(const std::string filename) typedef itk::ImageFileReader > ImageReader; //InternalPixelType != PixelType for vector images typename ImageReader::Pointer reader = ImageReader::New(); reader->SetFileName(filename.c_str()); - reader->AddObserver(itk::ProgressEvent(), ProgressUpdates); + reader->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates); try { reader->Update(); @@ -1012,7 +1012,7 @@ bool File::WriteImageUsingITK(const std::string filename, itk::SmartPointerSetFileName(filename.c_str()); writer->SetInput(data); - writer->AddObserver(itk::ProgressEvent(), ProgressUpdates); + writer->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates); try { writer->Update(); diff --git a/include/milxImage.h b/include/milxImage.h index 74794ee..bd7b551 100644 --- a/include/milxImage.h +++ b/include/milxImage.h @@ -21,6 +21,7 @@ //ITK #include #include +#include #include #include #if (ITK_REVIEW || ITK_VERSION_MAJOR > 3) //Review only members @@ -439,6 +440,11 @@ class SMILI_EXPORT Image : public ImageBase \brief Returns the minimum pixel value of an image. */ static double ImageMinimum(itk::SmartPointer img); + /*! + \fn Image::ImageOrientation(itk::SmartPointer img) + \brief Returns the orientation flag of an image. + */ + static std::string ImageOrientation(itk::SmartPointer img); //Filters /*! @@ -2089,6 +2095,7 @@ void Image::Information(itk::SmartPointer img) } std::cout << " |" << std::endl; } + std::cout << "\nOrientation Flag: " << ImageOrientation(img) << std::endl; } template @@ -2115,6 +2122,67 @@ double Image::ImageMinimum(itk::SmartPointer img) return imageCalculatorFilter->GetMinimum(); } +template +std::string Image::ImageOrientation(itk::SmartPointer img) +{ + std::map codeToString; + + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_AIL] = "AIL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ASL] = "ASL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RAI] = "RAI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LAI] = "LAI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RPS] = "RPS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LPS] = "LPS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP] = "RIP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LIP] = "LIP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RSP] = "RSP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LSP] = "LSP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIA] = "RIA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LIA] = "LIA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RSA] = "RSA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LSA] = "LSA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IRP] = "IRP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ILP] = "ILP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SRP] = "SRP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SLP] = "SLP"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IRA] = "IRA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ILA] = "ILA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SRA] = "SRA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SLA] = "SLA"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RPI] = "RPI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LPI] = "LPI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RAS] = "RAS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LAS] = "LAS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PRI] = "PRI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PLI] = "PLI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ARI] = "ARI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ALI] = "ALI"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PRS] = "PRS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PLS] = "PLS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ARS] = "ARS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ALS] = "ALS"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IPR] = "IPR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SPR] = "SPR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IAR] = "IAR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SAR] = "SAR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IPL] = "IPL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SPL] = "SPL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IAL] = "IAL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SAL] = "SAL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PIR] = "PIR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PSR] = "PSR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_AIR] = "AIR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ASR] = "ASR"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PIL] = "PIL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PSL] = "PSL"; + codeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_INVALID] = "Unknown"; + + itk::SpatialOrientation::ValidCoordinateOrientationFlags orientFlag = itk::SpatialOrientationAdapter().FromDirectionCosines(img->GetDirection()); + std::string orientFlagStr = codeToString[orientFlag]; + + return orientFlagStr; +} + //Filters template itk::SmartPointer Image::CheckerBoard(itk::SmartPointer img, itk::SmartPointer imgToCheckerBoard, const int numberOfSquares) diff --git a/plugin/dicom/milxQtDICOMPlugin.cpp b/plugin/dicom/milxQtDICOMPlugin.cpp index 053c5b6..ceabbe5 100644 --- a/plugin/dicom/milxQtDICOMPlugin.cpp +++ b/plugin/dicom/milxQtDICOMPlugin.cpp @@ -19,6 +19,8 @@ #include +#include + //Image typedefs typedef unsigned char charPixelType; typedef itk::Image charImageType; @@ -794,7 +796,7 @@ void milxQtDICOMPlugin::showInputFileDialogAnonymize() inputAnonymizeDirectoryname = fileOpener->getExistingDirectory(&wizardAnonymize, tr("Select Open Directory"), path, - QFileDialog::DontResolveSymlinks); + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); txtInputAnonymizeName->setText(inputAnonymizeDirectoryname); } @@ -1061,7 +1063,6 @@ void milxQtDICOMPlugin::createWizardAnonymise() QLabel *label4 = new QLabel("Please provide the top directory in which the subjects' folders are located."); label4->setWordWrap(true); txtInputAnonymizeName = new QLineEdit; - txtInputAnonymizeName->setText(QDir::current().absolutePath()); QPushButton *btnInputName = new QPushButton; connect(btnInputName, SIGNAL(clicked()), this, SLOT(showInputFileDialogAnonymize())); btnInputName->setText("Browse..."); @@ -1082,7 +1083,6 @@ void milxQtDICOMPlugin::createWizardAnonymise() QLabel *label5 = new QLabel("Please provide the output directory."); label5->setWordWrap(true); txtOutputAnonymizeName = new QLineEdit; - txtOutputAnonymizeName->setText(QDir::current().absolutePath()); QPushButton *btnOutputName = new QPushButton; btnOutputName->setText("Browse..."); connect(btnOutputName, SIGNAL(clicked()), this, SLOT(showOutputFileDialogAnonymize())); @@ -1148,39 +1148,41 @@ void milxQtDICOMPlugin::createWizardAnonymise() QLabel *label10 = new QLabel("Anonymization options:"); label10->setWordWrap(true); - anonPatientInfo = new QCheckBox("Anonymize Patient info:", &wizardAnonymize); + anonPatientInfo = new QCheckBox("Anonymize Patient info", &wizardAnonymize); anonPatientInfo->setChecked(true); - anonPhysician = new QCheckBox("Anonymize Physician(s) info:", &wizardAnonymize); - anonOperator = new QCheckBox("Anonymize Operator info:", &wizardAnonymize); + anonPhysician = new QCheckBox("Anonymize Physician(s) info", &wizardAnonymize); + anonOperator = new QCheckBox("Anonymize Operator info", &wizardAnonymize); + anonScanDate = new QCheckBox("Anonymize Scan Date", &wizardAnonymize); optionLayout->addWidget(label10); optionLayout->addWidget(checkboxPreserveFolderArc); optionLayout->addWidget(anonPatientInfo); optionLayout->addWidget(anonPhysician); optionLayout->addWidget(anonOperator); + optionLayout->addWidget(anonScanDate); optionLayout->setAlignment(Qt::AlignTop); QLabel *label9 = new QLabel("Items for default filename:"); label8->setWordWrap(true); - checkboxPatientName = new QCheckBox("Patient anonymized name:", &wizardAnonymize); + checkboxPatientName = new QCheckBox("Patient anonymized name", &wizardAnonymize); checkboxPatientName->setChecked(true); - checkboxPatientID = new QCheckBox("PatientID:", &wizardAnonymize); + checkboxPatientID = new QCheckBox("PatientID", &wizardAnonymize); checkboxPatientID->setChecked(true); - checkboxSeriesDate = new QCheckBox("SeriesDate:", &wizardAnonymize); + checkboxSeriesDate = new QCheckBox("SeriesDate", &wizardAnonymize); checkboxSeriesDate->setChecked(true); - checkboxSeriesTime = new QCheckBox("SeriesTime:", &wizardAnonymize); + checkboxSeriesTime = new QCheckBox("SeriesTime", &wizardAnonymize); checkboxSeriesTime->setChecked(true); - checkboxStudyID = new QCheckBox("StudyID:", &wizardAnonymize); - checkboxStudyDesc = new QCheckBox("StudyDesc:", &wizardAnonymize); + checkboxStudyID = new QCheckBox("StudyID", &wizardAnonymize); + checkboxStudyDesc = new QCheckBox("StudyDesc", &wizardAnonymize); checkboxStudyDesc->setChecked(true); - checkboxSeriesNumber = new QCheckBox("SeriesNumber:", &wizardAnonymize); + checkboxSeriesNumber = new QCheckBox("SeriesNumber", &wizardAnonymize); checkboxSeriesNumber->setChecked(true); checkboxSeriesNumber->setEnabled(false); - checkboxSequenceName = new QCheckBox("SequenceName:", &wizardAnonymize); + checkboxSequenceName = new QCheckBox("SequenceName", &wizardAnonymize); checkboxSequenceName->setChecked(true); - checkboxProtocolName = new QCheckBox("ProtocolName:", &wizardAnonymize); + checkboxProtocolName = new QCheckBox("ProtocolName", &wizardAnonymize); checkboxProtocolName->setChecked(true); - checkboxSeriesDescription = new QCheckBox("SeriesDescription:", &wizardAnonymize); + checkboxSeriesDescription = new QCheckBox("SeriesDescription", &wizardAnonymize); anonOptionLayout->addWidget(label8); anonOptionLayout->addWidget(label9); @@ -1229,13 +1231,13 @@ void milxQtDICOMPlugin::createConnections() bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QString &subject_output_folder, const QString &rel_dir, unsigned int index_subject, unsigned int index_dicom, bool &isFirst) { - QString logName= outputAnonymizeDirectoryname + QDir::separator() + "anonymization.log"; - std::string log = "Anonymizing image: " + input; - writeLog(logName, log); - MainWindow->printInfo(QString("Anonymizing: ") + input.c_str()); + QString logName= outputAnonymizeDirectoryname + QDir::separator() + "anonymization.log"; + std::string log = "Anonymizing image: " + input; + writeLog(logName, log); + MainWindow->printInfo(QString("Anonymizing: ") + input.c_str()); //TODO: This should be retrieved directly from dicom. - // And specific image type created then. + // And specific image type created then. typedef signed short shortPixelType; typedef itk::Image shortImageType; @@ -1245,16 +1247,17 @@ bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QStr std::string anonymization_value = outputPrefix.toStdString() + index.str(); ///Create 2 readers --> need two in case of T2 maps - ///TODO: Again this should be retrieved from the DICOM + ///TODO: Again this should be retrieved from the DICOM typedef itk::ImageFileReader< shortImageType > ReaderType; typedef itk::ImageFileReader< rgbImageType > rgbReaderType; ///First the image need to be read with a random type to able to read the dicom tags - ///and checkthe image type for saving later one + ///and checkthe image type for saving later one ReaderType::Pointer reader = ReaderType::New(); ImageIOType::Pointer gdcmImageIO = ImageIOType::New(); reader->SetFileName(input.c_str()); reader->SetImageIO( gdcmImageIO ); + reader->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates); try { reader->Update(); @@ -1281,43 +1284,47 @@ bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QStr ///And write QTextStream out(&file_mapping); - out.setCodec("UTF-8"); - out << QString::fromStdString(name_value) << "," << QString::fromStdString(anonymization_value) << "\n"; - file_mapping.close(); + out.setCodec("UTF-8"); + out << QString::fromStdString(name_value) << "," << QString::fromStdString(anonymization_value) << "\n"; + file_mapping.close(); } } ///If it is a T2 map need change image type / and re-read (unfortunate) - ///This should be read from the function rather than dicom tags but works - ///as well + ///This should be read from the function rather than dicom tags but works + ///as well std::string spl_per_px("0028|0002"); std::string spl_per_pxl_value; getTagValue(gdcmImageIO, spl_per_px, spl_per_pxl_value); bool isRGB = false; if (spl_per_pxl_value == "3") { - isRGB = true; + isRGB = true; } ///List of DICOM tags to strip std::vector dicomTags; if (anonPatientInfo->isChecked()) { - dicomTags.push_back("0010|0010"); - dicomTags.push_back("0010|0020"); + dicomTags.push_back("0010|0010"); //name + dicomTags.push_back("0010|0020"); //id dicomTags.push_back("0010|1005"); dicomTags.push_back("0010|1040"); dicomTags.push_back("0010|2154"); + dicomTags.push_back("0010|0030"); //DOB + dicomTags.push_back("0010|0032"); //DOB Time + dicomTags.push_back("0010|1020"); //size + dicomTags.push_back("0010|1030"); //weight } if (anonPhysician->isChecked()) { - dicomTags.push_back("0008|0090"); + dicomTags.push_back("0008|0090"); //phys name dicomTags.push_back("0008|0092"); dicomTags.push_back("0008|0094"); - dicomTags.push_back("0008|1048"); - dicomTags.push_back("0008|1050"); - dicomTags.push_back("0008|1060"); + dicomTags.push_back("0008|1048"); //phys record + dicomTags.push_back("0008|1050"); //perform phys name + dicomTags.push_back("0008|1060"); //phys read dicomTags.push_back("0032|1032"); dicomTags.push_back("0040|0006"); dicomTags.push_back("4008|0114"); @@ -1327,6 +1334,14 @@ bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QStr { dicomTags.push_back("0008|1070"); } + + if (anonScanDate->isChecked()) + { + dicomTags.push_back("0008|002A"); //acq date time + dicomTags.push_back("0008|0020"); //study date + dicomTags.push_back("0008|0021"); //series date + dicomTags.push_back("0008|0022"); //acq date + } ///Create output directory QString outputSequence = subject_output_folder + QDir::separator(); @@ -1339,13 +1354,13 @@ bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QStr std::string tag1("0020|0011"); std::string append1; getTagValue(gdcmImageIO, tag1, append1); - removeForbiddenChar(append1, "\\/:*?\"<>|"); + removeForbiddenChar(append1, "\\/:*?\"<>|"); outputSequence = outputSequence + QString::fromStdString(append1) + "_"; std::string tag2("0018|0024"); std::string append2; getTagValue(gdcmImageIO, tag2, append2); - removeForbiddenChar(append2, "\\/:*?\"<>|"); + removeForbiddenChar(append2, "\\/:*?\"<>|"); outputSequence = outputSequence + QString::fromStdString(append2); } @@ -1356,22 +1371,22 @@ bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QStr exist = QDir().mkpath(outputSequence); if (! exist) { - MainWindow->printError("Failed to create directory: " + outputSequence); + MainWindow->printError("Failed to create directory: " + outputSequence); std::cout << "Create fail: " << anonymization_value << std::endl; return false; } } - ///Write some debug on the type of images - log = "Component: [" + gdcmImageIO->GetComponentTypeAsString(gdcmImageIO->GetInternalComponentType()) + "]"; - log += ", Pixel type: [" + gdcmImageIO->GetPixelTypeAsString(gdcmImageIO->GetPixelType()) + "]\n"; - writeLog(logName, log); + ///Write some debug on the type of images + log = "Component: [" + gdcmImageIO->GetComponentTypeAsString(gdcmImageIO->GetInternalComponentType()) + "]"; + log += ", Pixel type: [" + gdcmImageIO->GetPixelTypeAsString(gdcmImageIO->GetPixelType()) + "]\n"; + writeLog(logName, log); ///Change dicom header and re-write file if (!isRGB) // If normal image - { - log = "Changing header"; - writeLog(logName, log); + { + log = "Changing header"; + writeLog(logName, log); DictionaryType & dictionary = floatImg->GetMetaDataDictionary(); std::vector::iterator dicomTagIterator; for (dicomTagIterator = dicomTags.begin(); dicomTagIterator != dicomTags.end(); dicomTagIterator++) @@ -1390,46 +1405,48 @@ bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QStr writer1->SetInput(floatImg); writer1->SetFileName(filename.c_str()); writer1->SetImageIO( gdcmImageIO); - log = "Writing image as " + filename; - writeLog(logName, log); - MainWindow->printInfo(QString("Writing image as: ") + filename.c_str()); + writer1->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates); + log = "Writing image as " + filename; + writeLog(logName, log); + MainWindow->printInfo(QString("Writing image as: ") + filename.c_str()); try { writer1->Update(); } catch (itk::ExceptionObject &ex) { - MainWindow->printError(ex.GetDescription()); + MainWindow->printError(ex.GetDescription()); std::cerr << ex << std::endl; return false; } } else // If RGB image { - rgbReaderType::Pointer readerrgb = rgbReaderType::New(); - - gdcmImageIO = NULL; - gdcmImageIO = ImageIOType::New(); - readerrgb->SetFileName(input.c_str()); - readerrgb->SetImageIO(gdcmImageIO); - try - { - readerrgb->Update(); - } - catch (itk::ExceptionObject &ex) - { - std::cerr << ex << std::endl; - return false; - } - rgbImageType::Pointer rgbImg = readerrgb->GetOutput(); - - ImageIOType::Pointer gdcmImageIO2 = ImageIOType::New(); - - log = "Changing header"; - writeLog(logName, log); + rgbReaderType::Pointer readerrgb = rgbReaderType::New(); + + gdcmImageIO = NULL; + gdcmImageIO = ImageIOType::New(); + readerrgb->SetFileName(input.c_str()); + readerrgb->SetImageIO(gdcmImageIO); + readerrgb->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates); + try + { + readerrgb->Update(); + } + catch (itk::ExceptionObject &ex) + { + std::cerr << ex << std::endl; + return false; + } + rgbImageType::Pointer rgbImg = readerrgb->GetOutput(); + + ImageIOType::Pointer gdcmImageIO2 = ImageIOType::New(); + + log = "Changing header"; + writeLog(logName, log); DictionaryType & dictionary = rgbImg->GetMetaDataDictionary(); - std::vector::iterator dicomTagIterator; + std::vector::iterator dicomTagIterator; for (dicomTagIterator = dicomTags.begin(); dicomTagIterator != dicomTags.end(); dicomTagIterator++) { itk::EncapsulateMetaData(dictionary, *dicomTagIterator, anonymization_value); @@ -1440,34 +1457,35 @@ bool milxQtDICOMPlugin::anonymizeDicomImage(const std::string &input, const QStr makeFilename(outputSequence, gdcmImageIO, index_dicom, filename, index_subject); typedef itk::ImageFileWriter< rgbImageType > Writer1Type; - gdcmImageIO2->SetMetaDataDictionary(dictionary); - gdcmImageIO2->SetUseCompression(gdcmImageIO->GetUseCompression()); - gdcmImageIO2->SetIORegion(gdcmImageIO->GetIORegion()); - gdcmImageIO2->SetUIDPrefix(gdcmImageIO->GetUIDPrefix()); - gdcmImageIO2->KeepOriginalUIDOn(); + gdcmImageIO2->SetMetaDataDictionary(dictionary); + gdcmImageIO2->SetUseCompression(gdcmImageIO->GetUseCompression()); + gdcmImageIO2->SetIORegion(gdcmImageIO->GetIORegion()); + gdcmImageIO2->SetUIDPrefix(gdcmImageIO->GetUIDPrefix()); + gdcmImageIO2->KeepOriginalUIDOn(); Writer1Type::Pointer writer1 = Writer1Type::New(); writer1->SetInput(rgbImg); - //writer1->SetMetaDataDictionary(dictionary); + //writer1->SetMetaDataDictionary(dictionary); writer1->SetFileName(filename.c_str()); - writer1->SetImageIO(gdcmImageIO2); - writer1->UseInputMetaDataDictionaryOff(); - log = "Writing image as " + filename; - writeLog(logName, log); - MainWindow->printInfo(QString("Writing image as: ") + filename.c_str()); + writer1->SetImageIO(gdcmImageIO2); + writer1->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates); + writer1->UseInputMetaDataDictionaryOff(); + log = "Writing image as " + filename; + writeLog(logName, log); + MainWindow->printInfo(QString("Writing image as: ") + filename.c_str()); try { writer1->Update(); } catch (itk::ExceptionObject &ex) { - MainWindow->printError(ex.GetDescription()); + MainWindow->printError(ex.GetDescription()); std::cerr << ex << std::endl; return false; } } - log = "Success\n"; - writeLog(logName, log); + log = "Success\n"; + writeLog(logName, log); return true; } diff --git a/plugin/dicom/milxQtDICOMPlugin.h b/plugin/dicom/milxQtDICOMPlugin.h index 122083f..20877b5 100644 --- a/plugin/dicom/milxQtDICOMPlugin.h +++ b/plugin/dicom/milxQtDICOMPlugin.h @@ -335,6 +335,7 @@ public slots: QCheckBox *anonPatientInfo; QCheckBox *anonPhysician; QCheckBox *anonOperator; + QCheckBox *anonScanDate; //data milxQtImage *image; //main window owner diff --git a/src/Qt/milxQtImage.cpp b/src/Qt/milxQtImage.cpp index 07ba530..8942660 100644 --- a/src/Qt/milxQtImage.cpp +++ b/src/Qt/milxQtImage.cpp @@ -1523,6 +1523,17 @@ void milxQtImage::imageInformation() printInfo("|" + QString::number(direction(0,0)) + ", " + QString::number(direction(0,1)) + ", " + QString::number(direction(0,2)) + "|"); printInfo("|" + QString::number(direction(1,0)) + ", " + QString::number(direction(1,1)) + ", " + QString::number(direction(1,2)) + "|"); printInfo("|" + QString::number(direction(2,0)) + ", " + QString::number(direction(2,1)) + ", " + QString::number(direction(2,2)) + "|"); + + QString orientFlagStr; + if(eightbit) + orientFlagStr = milx::Image::ImageOrientation(imageChar).c_str(); + else if(integer) + orientFlagStr = milx::Image::ImageOrientation(imageInt).c_str(); + else if(rgb) + orientFlagStr = milx::Image::ImageOrientation(imageRGB).c_str(); + else + orientFlagStr = milx::Image::ImageOrientation(imageFloat).c_str(); + printInfo("Orientation Flag: " + orientFlagStr); } emit done(-1); diff --git a/src/Qt/milxQtModel.cpp b/src/Qt/milxQtModel.cpp index c3ee0e9..8cc74ca 100644 --- a/src/Qt/milxQtModel.cpp +++ b/src/Qt/milxQtModel.cpp @@ -285,6 +285,7 @@ void milxQtModel::refresh() #else modelMapper->SetInputData(model.Result()); #endif + resetScalarRange(); modelMapper->Update(); milxQtRenderWindow::refresh(); }