Remove ITK, use simple DICOM image reader read DICOM files.

This commit is contained in:
Krad
2022-02-11 13:28:51 +08:00
parent f3dbb5f12e
commit c6b16f0742
13 changed files with 876 additions and 426 deletions

View File

@@ -25,15 +25,20 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/include/util ${CMAKE_SOURCE_DIR}/src/include/util
) )
add_subdirectory(thirdparty)
set(VTK_DIR "E:/3-Library/VTK-8.2.0/VTK/lib/cmake/vtk-8.2") set(VTK_DIR "D:/Libs/binary/VTK8.1.2/lib/cmake/vtk-8.2")
set(Qt5_DIR "D:/Qt/Qt5.12.0/5.12.0/msvc2017_64/lib/cmake/Qt5") set(Qt5_DIR "D:/Qt/Qt5.12.0/5.12.0/msvc2017_64/lib/cmake/Qt5")
set(ITK_DIR "E:/3-Library/InsightToolkit-4.12.0/ITK/lib/cmake/ITK-4.12") #set(ITK_DIR "E:/3-Library/InsightToolkit-4.12.0/ITK/lib/cmake/ITK-4.12")
set(DCMTK_DIR "E:/3-Library/Dcmtk-3.6.4/DCMTK/cmake") set(DCMTK_DIR "D:/Libs/binary/DCMTK/cmake")
set(ITK_RUNTIME_DIRS "E:/3-Library/InsightToolkit-4.12.0/ITK/bin")
set(DCMTK_RUNTIME_DIRS "E:/3-Library/Dcmtk-3.6.4/DCMTK/bin")
find_package(DCMTK REQUIRED)
include_directories(${DCMTK_INCLUDE_DIRS})
#
#set(ITK_RUNTIME_DIRS "E:/3-Library/InsightToolkit-4.12.0/ITK/bin")
#set(DCMTK_RUNTIME_DIRS "E:/3-Library/Dcmtk-3.6.4/DCMTK/bin")
#
set(DCM_NETWORK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/thirdparty/dcm_network) set(DCM_NETWORK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/thirdparty/dcm_network)
set(DCM_NETWORK_RUNTIME_DIRS ${CMAKE_BINARY_DIR}/thirdparty/dcm_network) set(DCM_NETWORK_RUNTIME_DIRS ${CMAKE_BINARY_DIR}/thirdparty/dcm_network)
@@ -67,22 +72,17 @@ find_package(VTK REQUIRED)
include(${VTK_USE_FILE}) include(${VTK_USE_FILE})
target_link_libraries(${PROJECT_NAME} ${VTK_LIBRARIES}) target_link_libraries(${PROJECT_NAME} ${VTK_LIBRARIES})
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
target_link_libraries(${PROJECT_NAME} ${ITK_LIBRARIES})
find_package(DCMTK REQUIRED)
include_directories(${DCMTK_INCLUDE_DIRS})
if(DCMTK_LIBRARIES) if(DCMTK_LIBRARIES)
target_link_libraries(${PROJECT_NAME} ${DCMTK_LIBRARIES}) target_link_libraries(${PROJECT_NAME} ${DCMTK_LIBRARIES})
endif() endif()
add_subdirectory(thirdparty)
if(MSVC) if(MSVC)
set_target_properties(${PROJECT_NAME} PROPERTIES VS_DEBUGGER_ENVIRONMENT "path=${VTK_RUNTIME_DIRS};${Qt5_DIR}/../../../bin/;${ITK_RUNTIME_DIRS};${DCMTK_RUNTIME_DIRS};${DCM_NETWORK_RUNTIME_DIRS}/$<CONFIG>") set_target_properties(${PROJECT_NAME} PROPERTIES VS_DEBUGGER_ENVIRONMENT "path=${VTK_RUNTIME_DIRS};${Qt5_DIR}/../../../bin/;${DCMTK_RUNTIME_DIRS};${DCM_NETWORK_RUNTIME_DIRS}/$<CONFIG>")
endif(MSVC) endif(MSVC)
include_directories(${DCM_NETWORK_INCLUDE_DIRS}) include_directories(${DCM_NETWORK_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} dcm_network) target_link_libraries(${PROJECT_NAME} dcm_network)
add_dependencies(${PROJECT_NAME} dcm_network) add_dependencies(${PROJECT_NAME} dcm_network)

View File

@@ -16,8 +16,9 @@ public:
class SeriesInstance; class SeriesInstance;
class DICOMDirectoryHelper;
class ExtendMedicalImageProperties;
class vtkDICOMImageReader2;
class DicomLoader { class DicomLoader {
public: public:
@@ -25,9 +26,9 @@ public:
static DicomLoader *GetInstance(); static DicomLoader *GetInstance();
static void itkReaderProCallbackFunction_FILE(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data); // static void itkReaderProCallbackFunction_FILE(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data);
static void itkReaderProCallbackFunction_DIR(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data); // static void itkReaderProCallbackFunction_DIR(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data);
static void itkReaderEndCallbackFunction(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data); // static void itkReaderEndCallbackFunction(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data);
DicomTagInfo_t* createDicomTagsInfo(); DicomTagInfo_t* createDicomTagsInfo();
@@ -73,10 +74,13 @@ private:
//once //once
ConnectorType::Pointer m_itkConnector; DICOMDirectoryHelper * DICOMHelper;
SeriesReaderType::Pointer m_itkSeriesReader; ExtendMedicalImageProperties * currentImageProperty;
ImageIOType::Pointer m_gdcmIO; vtkDICOMImageReader2 * reader;
InputNamesGeneratorType::Pointer m_inputNames; // ConnectorType::Pointer m_itkConnector;
// SeriesReaderType::Pointer m_itkSeriesReader;
// ImageIOType::Pointer m_gdcmIO;
// InputNamesGeneratorType::Pointer m_inputNames;
AddDicomType m_addType; AddDicomType m_addType;

View File

@@ -1,8 +1,8 @@
#pragma once #pragma once
#include "global/include_all.h" #include "global/include_all.h"
#include "global/include_vitk.h"
#include "global/QGlobals.h" #include "global/QGlobals.h"
#include "ActorDraggableInteractorStyle.h" #include "ActorDraggableInteractorStyle.h"
#include "global/include_vitk.h"
//#include "QVTKWidget.h" //#include "QVTKWidget.h"
#include <memory> #include <memory>

View File

@@ -3,12 +3,12 @@
#include <QObject> #include <QObject>
#include "exportoptions.h" #include "exportoptions.h"
#include <itkImage.h> //#include <itkImage.h>
#include <itkGDCMImageIO.h> //#include <itkGDCMImageIO.h>
#include <itkImageSeriesReader.h> //#include <itkImageSeriesReader.h>
#include <itkImageSeriesWriter.h> //#include <itkImageSeriesWriter.h>
#include <itkImageToVTKImageFilter.h> //#include <itkImageToVTKImageFilter.h>
#include <itkGDCMSeriesFileNames.h> //#include <itkGDCMSeriesFileNames.h>
#include "base/infinitiViewer.h" #include "base/infinitiViewer.h"
#include <vtkRenderer.h> #include <vtkRenderer.h>
#include <vtkSmartPointer.h> #include <vtkSmartPointer.h>
@@ -23,8 +23,8 @@
#include <qfileinfo.h> #include <qfileinfo.h>
#include <qdir.h> #include <qdir.h>
#include <sstream> #include <sstream>
#include "itkMetaDataObject.h" //#include "itkMetaDataObject.h"
#include "itkMetaDataDictionary.h" //#include "itkMetaDataDictionary.h"
class DicomExporter : public QObject class DicomExporter : public QObject
@@ -74,17 +74,17 @@ private:
//bmp jpg png tiff exprt releated objects //bmp jpg png tiff exprt releated objects
static const unsigned int InputDimensionExport = 3; static const unsigned int InputDimensionExport = 3;
typedef signed short PixelTypeExport; typedef signed short PixelTypeExport;
typedef itk::Image<PixelTypeExport, InputDimensionExport> InputImageTypeExport; // typedef itk::Image<PixelTypeExport, InputDimensionExport> InputImageTypeExport;
typedef itk::GDCMImageIO ImageIOTypeExport; // typedef itk::GDCMImageIO ImageIOTypeExport;
typedef itk::ImageSeriesReader<InputImageTypeExport> SeriesReaderTypeExport; // typedef itk::ImageSeriesReader<InputImageTypeExport> SeriesReaderTypeExport;
typedef itk::ImageToVTKImageFilter<InputImageTypeExport> ConnectorTypeExport; // typedef itk::ImageToVTKImageFilter<InputImageTypeExport> ConnectorTypeExport;
typedef itk::GDCMSeriesFileNames InputNamesGeneratorTypeExport; // typedef itk::GDCMSeriesFileNames InputNamesGeneratorTypeExport;
//dicom export releated objects //dicom export releated objects
typedef signed short OutputPixelType; typedef signed short OutputPixelType;
static const unsigned int OutputDimension = 2; static const unsigned int OutputDimension = 2;
typedef itk::Image<OutputPixelType, OutputDimension> Image2DType; // typedef itk::Image<OutputPixelType, OutputDimension> Image2DType;
typedef itk::ImageSeriesWriter<InputImageTypeExport, Image2DType> SeriesWriterType; // typedef itk::ImageSeriesWriter<InputImageTypeExport, Image2DType> SeriesWriterType;
private: private:
void initVTK(); void initVTK();
@@ -102,7 +102,7 @@ private:
void exportDicom(const QString& fileName); void exportDicom(const QString& fileName);
void exportSingleDicomFile(const QString& fileName); void exportSingleDicomFile(const QString& fileName);
void exportDicomDirectory(const QString& fileName); void exportDicomDirectory(const QString& fileName);
void modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray); // void modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray);
void caculateExportTotalCount(); void caculateExportTotalCount();
private: private:
@@ -111,10 +111,10 @@ private:
int exportedNumber;//the exported image index int exportedNumber;//the exported image index
//itk vtk releated objects //itk vtk releated objects
ImageIOTypeExport::Pointer m_gdcmIOExport; // ImageIOTypeExport::Pointer m_gdcmIOExport;
SeriesReaderTypeExport::Pointer m_itkSeriesReaderExport; // SeriesReaderTypeExport::Pointer m_itkSeriesReaderExport;
ConnectorTypeExport::Pointer m_itkConnectorExport; // ConnectorTypeExport::Pointer m_itkConnectorExport;
InputNamesGeneratorTypeExport::Pointer m_inputNamesExport; // InputNamesGeneratorTypeExport::Pointer m_inputNamesExport;
vtkSmartPointer<vtkRenderWindow> m_glrenWinExport; vtkSmartPointer<vtkRenderWindow> m_glrenWinExport;
vtkSmartPointer<infinitiViewer> m_imageViewerExport; vtkSmartPointer<infinitiViewer> m_imageViewerExport;
}; };

View File

@@ -61,7 +61,6 @@
//newly added //newly added
#include <vtkCamera.h> #include <vtkCamera.h>
#include <itkCommand.h>
#include <vtkOpenGLRenderWindow.h> #include <vtkOpenGLRenderWindow.h>
#include <QSurfaceFormat> #include <QSurfaceFormat>
#include <vtkGenericOpenGLRenderWindow.h> #include <vtkGenericOpenGLRenderWindow.h>
@@ -73,13 +72,6 @@
#include <QVTKOpenGLNativeWidget.h> #include <QVTKOpenGLNativeWidget.h>
//ITK headers //ITK headers
#include <itkImage.h>
#include <itkGDCMImageIO.h>
#include <itkGDCMSeriesFileNames.h>
#include <itkImageSeriesReader.h>
#include <itkImageToVTKImageFilter.h>
#include <itkImageFileWriter.h>
#include <itkImageSeriesWriter.h>
//#include <vnl/vnl_vector.hxx> //#include <vnl/vnl_vector.hxx>
//#include <vnl/algo/vnl_svd.hxx> //#include <vnl/algo/vnl_svd.hxx>
//#include <vnl/algo/vnl_qr.hxx> //#include <vnl/algo/vnl_qr.hxx>
@@ -95,23 +87,9 @@ static const unsigned int InputDimension = 3;
static const unsigned int OutputDimension = 2; static const unsigned int OutputDimension = 2;
typedef signed short PixelType; typedef signed short PixelType;
typedef itk::Image<PixelType, InputDimension> InputImageType;
typedef itk::GDCMImageIO ImageIOType;
typedef itk::GDCMSeriesFileNames InputNamesGeneratorType;
typedef itk::ImageToVTKImageFilter<InputImageType> ConnectorType;
typedef itk::MetaDataDictionary DictionaryType;
typedef itk::MetaDataObject<std::string> MetaDataStringType;
typedef itk::ImageSeriesReader<InputImageType> SeriesReaderType;
typedef std::vector< std::string > FilenamesContainer; typedef std::vector< std::string > FilenamesContainer;
typedef FilenamesContainer FileNamesContainerType; typedef FilenamesContainer FileNamesContainerType;
typedef itk::ImageFileWriter<InputImageType> ImageWriterType;
typedef itk::Image< PixelType, OutputDimension > Image2DType;
typedef itk::ImageSeriesWriter <InputImageType, Image2DType > SeriesWriterType;

View File

@@ -0,0 +1,175 @@
//
// Created by Krad on 2022/2/8.
//
#include "DICOMDirectoryHelper.h"
#include "dcmtk/dcmdata/dcfilefo.h"
#include "dcmtk/dcmdata/dcdatset.h"
#include "ExtendMedicalImageProperties.h"
#include <vtkDirectory.h>
#include <vtkNew.h>
#include <unordered_map>
#include <algorithm>
struct DICOMTag{
Uint16 group;
Uint16 element;
const char * des;
};
DICOMTag dicom_tags[] = {
{0x0002, 0x0002, "Media storage SOP class uid"},
{0x0002, 0x0003, "Media storage SOP inst uid"},
{0x0002, 0x0010, "Transfer syntax uid"},
{0x0002, 0x0012, "Implementation class uid"},
{0x0008, 0x0018, "Image UID"},
{0x0008, 0x0020, "Series date"},
{0x0008, 0x0030, "Series time"},
{0x0008, 0x0060, "Modality"},
{0x0008, 0x0070, "Manufacturer"},
{0x0008, 0x1060, "Physician"},
{0x0018, 0x0050, "slice thickness"},
{0x0018, 0x0060, "kV"},
{0x0018, 0x0088, "slice spacing"},
{0x0018, 0x1100, "Recon diameter"},
{0x0018, 0x1151, "mA"},
{0x0018, 0x1210, "Recon kernel"},
{0x0020, 0x000d, "Study UID"},
{0x0020, 0x000e, "Series UID"},
{0x0020, 0x0013, "Image number"},
{0x0020, 0x0032, "Patient position"},
{0x0020, 0x0037, "Patient position cosines"},
{0x0020, 0x1041, "Slice location"},
{0x0028, 0x0010, "Num rows"},
{0x0028, 0x0011, "Num cols"},
{0x0028, 0x0030, "pixel spacing"},
{0x0028, 0x0100, "Bits allocated"},
{0x0028, 0x0120, "pixel padding"},
{0x0028, 0x1052, "pixel offset"}
};
void DICOMDirectoryHelper::getDirectoryProperties(const char * rootPath, DICOMFileMap& result){
vtkNew<vtkDirectory> dir;
dir->Open(rootPath);
vtkIdType fileCount = dir->GetNumberOfFiles();
for (vtkIdType i = 0; i < fileCount; ++i) {
const char* file_path = dir->GetFile(i);
if (strcmp(".",file_path)==0 || strcmp("..",file_path)==0 ) continue;
std::string path(rootPath);
path.append("\\");
path.append(file_path);
std::cout<<"file path:"<<path<<std::endl;
if (dir->FileIsDirectory(path.c_str()))
{
getDirectoryProperties(path.c_str(), result);
}
else {
getFileProperty(path, result);
}
}
}
void DICOMDirectoryHelper::getFileProperty(const std::string &path, DICOMFileMap& result) {
DcmFileFormat file;
if (file.loadFile(path).good()) {
DcmDataset *dataset = file.getDataset();
std::string SeriesUID;
dataset->findAndGetOFString(DcmTagKey(0x0020, 0x000e), SeriesUID);
long SeriesNumber = 0;
dataset->findAndGetSint32(DcmTagKey(0x0020, 0x0011), SeriesNumber);
long AcquisitionNumber = 0;
dataset->findAndGetSint32(DcmTagKey(0x0020, 0x0012), AcquisitionNumber);
long InstanceNumber = 0;
dataset->findAndGetSint32(DcmTagKey(0x0020, 0x0013), InstanceNumber);
if (!result.count(SeriesUID)) {
ExtendMedicalImageProperties *seriesProperty = ExtendMedicalImageProperties::New();
#define ReadTAGToProperty(Name, group, element)\
std::string Name;\
dataset->findAndGetOFString(DcmTagKey(group, element), Name);\
seriesProperty->Set##Name(Name.c_str());
ReadTAGToProperty(PatientID, 0x0010, 0x0020);
ReadTAGToProperty(PatientName, 0x0010, 0x0010);
ReadTAGToProperty(PatientBirthDate, 0x0010, 0x0030);
ReadTAGToProperty(PatientSex, 0x0010, 0x0040);
ReadTAGToProperty(StudyDate, 0x0008, 0x0020);
ReadTAGToProperty(StudyTime, 0x0008, 0x0030);
ReadTAGToProperty(Modality, 0x0008, 0x0060);
ReadTAGToProperty(InstitutionName, 0x0008, 0x0080);
ReadTAGToProperty(StudyDescription, 0x0008, 0x1030);
ReadTAGToProperty(SeriesDescription, 0x0008, 0x103E);
ReadTAGToProperty(StudyUID, 0x0020, 0x000d);
ReadTAGToProperty(StudyID, 0x0020, 0x0010);
seriesProperty->SetSeriesUID(SeriesUID.c_str());
seriesProperty->SetSeriesNumber(SeriesNumber);
double WindowCenter = 0.0;
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1050), WindowCenter);
double WindowWidth = 0.0;
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1051), WindowWidth);
seriesProperty->AddWindowLevelPreset(WindowWidth, WindowCenter);
double Spacing[2] = {0.0,0.0};
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x0030), Spacing[0], 0);
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x0030), Spacing[1], 1);
seriesProperty->SetSpacing(Spacing);
seriesProperties.push_back(seriesProperty);
//暂时不考虑acqnumber的影响
//seriesProperty->SetAcquisitionNumber(AcquisitionNumber);
}
char buffer[256] = {0};
sprintf(buffer, "%ld-%ld", AcquisitionNumber, InstanceNumber);
printf("%s\r\n", path.c_str());
result[SeriesUID][buffer] = {std::move(path), SeriesNumber, AcquisitionNumber, InstanceNumber};
}
}
void DICOMDirectoryHelper::Update() {
std::unordered_map<std::string, std::unordered_map<std::string,DICOMFileRefValue>> series;
getDirectoryProperties(this->dirName.c_str(), series);
//sort files
for (auto &pair : series) {
auto iterator = std::find_if(seriesProperties.begin(),seriesProperties.end(),
[=](ExtendMedicalImageProperties* val){
return strcmp(val->GetSeriesUID(), pair.first.c_str()) == 0;
}
);
if (iterator < seriesProperties.end()){
auto files = (*iterator)->GetFileNames();
std::vector<DICOMFileRefValue> vector;
for (auto f : pair.second) {
// printf("%s\r\n",f.second.FilePath.c_str());
vector.emplace_back(std::move(f.second));
}
std::sort(vector.begin(), vector.end(), [](const DICOMFileRefValue &v1, const DICOMFileRefValue &v2) {
return v1.SeriesNumber != v2.SeriesNumber ? (v1.SeriesNumber < v2.SeriesNumber) :
(v1.AcquisitionNumber != v2.AcquisitionNumber ? (v1.AcquisitionNumber < v2.AcquisitionNumber) :
(v1.InstanceNumber < v2.InstanceNumber));
});
std::for_each(vector.begin(), vector.end(),[=](auto v){
// printf("%s\r\n",v.FilePath.c_str());
files->emplace_back(std::move(v.FilePath));
});
}
}
SeriesCount = seriesProperties.size();
}
ExtendMedicalImageProperties* DICOMDirectoryHelper::GetSeries(int idx) {
if (seriesProperties.size() <= idx) return nullptr;
return seriesProperties[idx];
}
void DICOMDirectoryHelper::Clear() {
dirName.clear();
fileName.clear();
for (auto property : seriesProperties) {
property->Delete();
}
seriesProperties.clear();
SeriesCount = 0;
}

View File

@@ -0,0 +1,56 @@
//
// Created by Krad on 2022/2/8.
//
#ifndef DCMV_DICOMDIRECTORYHELPER_H
#define DCMV_DICOMDIRECTORYHELPER_H
#include <string>
#include <vector>
#include <unordered_map>
class ExtendMedicalImageProperties;
struct DICOMFileRefValue{
std::string FilePath;
long SeriesNumber = 0;
long AcquisitionNumber = 0;
long InstanceNumber = 0;
};
typedef std::unordered_map<std::string, std::unordered_map<std::string, DICOMFileRefValue>> DICOMFileMap;
class DICOMDirectoryHelper {
public:
DICOMDirectoryHelper()=default;
~DICOMDirectoryHelper(){
Clear();
} ;
void SetDirName(const char * dir){
Clear();
dirName = dir;
}
void SetFileName(const char * file){
Clear();
fileName = file;
}
void Clear();
void Update();
int GetSeriesCount(){
return SeriesCount;
}
ExtendMedicalImageProperties* GetSeries(int idx);
private:
std::string dirName;
std::string fileName;
int SeriesCount = 0;
std::vector<ExtendMedicalImageProperties*> seriesProperties;
void getDirectoryProperties(const char *rootPath,
DICOMFileMap &result);
void getFileProperty(const std::string &path, DICOMFileMap &result);
};
#endif //DCMV_DICOMDIRECTORYHELPER_H

View File

@@ -3,7 +3,12 @@
#include <QMainWindow> #include <QMainWindow>
#include <QStatusBar> #include <QStatusBar>
#include "base/seriesinstance.h" #include "base/seriesinstance.h"
#include "DICOMDirectoryHelper.h"
#include "ExtendMedicalImageProperties.h"
#include "vtkDICOMImageReader2.h"
#include <map> #include <map>
#include <algorithm>
#include <vtkStringArray.h>
#include <qDebug> #include <qDebug>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@@ -94,16 +99,21 @@ DicomLoader* DicomLoader::GetInstance() {
DicomLoader::DicomLoader():m_addType(AddDicomType::DUPLICATE_TYPE) { DicomLoader::DicomLoader():m_addType(AddDicomType::DUPLICATE_TYPE) {
m_itkSeriesReader = SeriesReaderType::New(); // m_itkSeriesReader = SeriesReaderType::New();
m_itkConnector = ConnectorType::New(); // m_itkConnector = ConnectorType::New();
m_gdcmIO = ImageIOType::New(); // m_gdcmIO = ImageIOType::New();
m_inputNames = InputNamesGeneratorType::New(); // m_inputNames = InputNamesGeneratorType::New();
DICOMHelper = new DICOMDirectoryHelper;
reader = vtkDICOMImageReader2::New();
//transfer to series after! //transfer to series after!
m_patients.clear(); m_patients.clear();
} }
DicomLoader::~DicomLoader() { DicomLoader::~DicomLoader() {
delete DICOMHelper;
reader->Delete();
reader = nullptr;
delete instance; delete instance;
} }
@@ -163,8 +173,6 @@ bool DicomLoader::IsDuplicate(UniqueIDInfo_t* unique)
} }
void DicomLoader::InitFromCopy(SeriesInstance* instance) void DicomLoader::InitFromCopy(SeriesInstance* instance)
{ {
//copy data from existing instance! //copy data from existing instance!
@@ -181,7 +189,7 @@ void DicomLoader::InitFromCopy(SeriesInstance* instance)
if (exists->getUniqueID()->open_mode == DIR_OPEN_MODE) if (exists->getUniqueID()->open_mode == DIR_OPEN_MODE)
{ {
//vector deep copy //vector deep copy
//exists->m_fileNames = instance->m_fileNames;This is a bug<75><67> //exists->m_fileNames = instance->m_fileNames;This is a bug<75><67>
instance->m_fileNames = exists->m_fileNames; instance->m_fileNames = exists->m_fileNames;
} }
} }
@@ -191,12 +199,15 @@ void DicomLoader::InitFromRead(SeriesInstance* instance)//, DicomTagInfo_t* tag_
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//You have to use DeepCopy on this condition,otherwise, the previous image will be flushed. //You have to use DeepCopy on this condition,otherwise, the previous image will be flushed.
instance->m_image->DeepCopy(m_itkConnector->GetOutput()); instance->m_image->DeepCopy(reader->GetOutput());
//instance->m_image = m_itkConnector->GetOutput(); //instance->m_image = m_itkConnector->GetOutput();
if (instance->getUniqueID()->open_mode == DIR_OPEN_MODE) if (instance->getUniqueID()->open_mode == DIR_OPEN_MODE)
{ {
instance->m_fileNames = m_inputNames->GetInputFileNames(); auto files = reader->GetDICOMFileNames();
std::for_each(files->begin(),files->end(),[=](auto v){
instance->m_fileNames.push_back(v);
});
} }
} }
@@ -343,7 +354,7 @@ bool DicomLoader::deleteSeriesInstance(SeriesInstance* old)
//DicomLoader *helper = DicomLoader::GetInstance(); //DicomLoader *helper = DicomLoader::GetInstance();
InstancesVecType* inst_vec = instance->getInstancesVec(*old->getUniqueID()); InstancesVecType* inst_vec = instance->getInstancesVec(*old->getUniqueID());
//if there is only one instance<63><65>do not delete //if there is only one instance<63><65>do not delete
if (inst_vec->size() == SINGLE_INSTANCE) if (inst_vec->size() == SINGLE_INSTANCE)
{ {
//Comment1:You should set Series Instance to no DicomImageView //Comment1:You should set Series Instance to no DicomImageView
@@ -541,44 +552,22 @@ SeriesInstance* DicomLoader::addSeriesInstance(SeriesInstance* instance,bool cop
void DicomLoader::ItkPreReadSeries(const std::string &dicomName, SeriesOpenMode openMode) void DicomLoader::ItkPreReadSeries(const std::string &dicomName, SeriesOpenMode openMode)
{ {
//m_itkSeriesReader->SetImageIO(gdcmIO); //m_itkSeriesReader->SetImageIO(gdcmIO);
m_itkSeriesReader->SetImageIO(m_gdcmIO);
if (openMode == FILE_OPEN_MODE) if (openMode == FILE_OPEN_MODE)
{ {
//m_itkSeriesReader->SetFileName(m_dicomName.toStdString()); //m_itkSeriesReader->SetFileName(m_dicomName.toStdString());
m_itkSeriesReader->SetFileName(dicomName); DICOMHelper->SetFileName(dicomName.c_str());
} }
if (openMode == DIR_OPEN_MODE) if (openMode == DIR_OPEN_MODE)
{ {
DICOMHelper->SetDirName(dicomName.c_str());
//Read the input series
m_inputNames->SetInputDirectory(dicomName.c_str());
const SeriesReaderType::FileNamesContainer & filenames = m_inputNames->GetInputFileNames();
//m_itkSeriesReader->SetFileNames(filenames);
m_itkSeriesReader->SetFileNames(filenames);
} }
DICOMHelper->Update();
try { if(DICOMHelper->GetSeriesCount()>0){
//m_itkSeriesReader->Update(); currentImageProperty = DICOMHelper->GetSeries(0);
m_itkSeriesReader->UpdateLargestPossibleRegion(); reader->SetFileNames(*(currentImageProperty->GetFileNames()));
m_itkSeriesReader->Update(); reader->Update();
} }
catch (itk::ExceptionObject &excp) {
std::cerr << "Exception thrown while reading the series" << std::endl;
std::cerr << excp << std::endl;
}
//Connector to convert ITK image data to VTK image data
//connector->SetInput(m_itkSeriesReader->GetOutput()); //Set ITK reader Output to connector you can replace it with filter
m_itkConnector->SetInput(m_itkSeriesReader->GetOutput());
try { //Exceptional handling
m_itkConnector->Update();
}
catch (itk::ExceptionObject & e) {
std::cerr << "exception in file reader " << std::endl;
std::cerr << e << std::endl;
}
} }
@@ -591,11 +580,12 @@ UniqueIDInfo_t* DicomLoader::createUniqueID(const std::string &dicomName, Series
pUniqueID->dicom_name = dicomName; pUniqueID->dicom_name = dicomName;
if (openMode == FILE_OPEN_MODE) if (openMode == FILE_OPEN_MODE)
{ {
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_INSTANCE_NUM, pUniqueID->instance_num); char buffer[16]={};
pUniqueID->instance_num=itoa(currentImageProperty->GetFileNames()->size(),buffer,10);
} }
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_PATIENT_NAME, pUniqueID->patient_name); pUniqueID->patient_name = currentImageProperty->GetPatientName();
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_STUDY_UID, pUniqueID->study_uid); pUniqueID->study_uid = currentImageProperty->GetStudyUID();
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_SERIES_UID, pUniqueID->series_uid); pUniqueID->series_uid = currentImageProperty->GetSeriesUID();
return pUniqueID; return pUniqueID;
} }
@@ -604,57 +594,57 @@ UniqueIDInfo_t* DicomLoader::createUniqueID(const std::string &dicomName, Series
void DicomLoader::setDirObservers(void* client) void DicomLoader::setDirObservers(void* client)
{ {
//Adding a reading progress observer to the reader so we can see how are we reading. //Adding a reading progress observer to the reader so we can see how are we reading.
itk::CStyleCommand::Pointer pcl = itk::CStyleCommand::New(); // itk::CStyleCommand::Pointer pcl = itk::CStyleCommand::New();
pcl->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderProCallbackFunction_DIR); // pcl->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderProCallbackFunction_DIR);
pcl->SetClientData(client); // pcl->SetClientData(client);
//m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl); // //m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl); // m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
//
itk::CStyleCommand::Pointer pcl2 = itk::CStyleCommand::New(); // itk::CStyleCommand::Pointer pcl2 = itk::CStyleCommand::New();
pcl2->SetClientData(client); // pcl2->SetClientData(client);
pcl2->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderEndCallbackFunction); // pcl2->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderEndCallbackFunction);
//m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2); // //m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2); // m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
} }
void DicomLoader::setFileObservers(void* client) void DicomLoader::setFileObservers(void* client)
{ {
//Adding a reading progress observer to the reader so we can see how are we reading. //Adding a reading progress observer to the reader so we can see how are we reading.
itk::CStyleCommand::Pointer pcl = itk::CStyleCommand::New(); // itk::CStyleCommand::Pointer pcl = itk::CStyleCommand::New();
pcl->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderProCallbackFunction_FILE); // pcl->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderProCallbackFunction_FILE);
pcl->SetClientData(client); // pcl->SetClientData(client);
//m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl); // //m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl); // m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
//
itk::CStyleCommand::Pointer pcl2 = itk::CStyleCommand::New(); // itk::CStyleCommand::Pointer pcl2 = itk::CStyleCommand::New();
pcl2->SetClientData(client); // pcl2->SetClientData(client);
pcl2->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderEndCallbackFunction); // pcl2->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderEndCallbackFunction);
//m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2); // //m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2); // m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
} }
void DicomLoader::itkReaderProCallbackFunction_FILE(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data) //void DicomLoader::itkReaderProCallbackFunction_FILE(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data)
{ //{
QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data); // QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data);
QString status = QString("Reading Images..."); // QString status = QString("Reading Images...");
qdv->statusBar()->showMessage(status); // qdv->statusBar()->showMessage(status);
} //}
void DicomLoader::itkReaderProCallbackFunction_DIR(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data) //void DicomLoader::itkReaderProCallbackFunction_DIR(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data)
{ //{
QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data); // QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data);
QString status = QString("Scanning Folder...(%1%)").arg(100 * obj->GetProgress()); // QString status = QString("Scanning Folder...(%1%)").arg(100 * obj->GetProgress());
qdv->statusBar()->showMessage(status); // qdv->statusBar()->showMessage(status);
} //}
//
void DicomLoader::itkReaderEndCallbackFunction(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data) //void DicomLoader::itkReaderEndCallbackFunction(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data)
//
{ //{
QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data); // QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data);
qdv->statusBar()->showMessage("Ready"); // qdv->statusBar()->showMessage("Ready");
} //}
// //
//void DicomLoader::copyDicomTagsInfo(SeriesInstance* origin, SeriesInstance* copy) //void DicomLoader::copyDicomTagsInfo(SeriesInstance* origin, SeriesInstance* copy)
//{ //{
@@ -690,40 +680,29 @@ DicomTagInfo_t* DicomLoader::createDicomTagsInfo()
std::string s_wl; std::string s_wl;
std::string s_ww; std::string s_ww;
for (int i = 0; i < 3; i++) info->spacing[0] = currentImageProperty->GetSpacing()[0];
{ info->spacing[1] = currentImageProperty->GetSpacing()[1];
info->spacing[i] = m_gdcmIO->GetSpacing(i); info->spacing[2] = currentImageProperty->GetSliceThicknessAsDouble();
}
m_gdcmIO->GetPatientName(PatientName); info->m_PatientName = currentImageProperty->GetPatientName();
info->m_PatientName = std::string(PatientName); info->m_StudyDescription = currentImageProperty->GetStudyDescription();
m_gdcmIO->GetStudyDescription(StudyDescription);
info->m_StudyDescription = std::string(StudyDescription);
m_gdcmIO->GetInstitution(Institution);
info->m_Institution = std::string(Institution);
m_gdcmIO->GetStudyDate(StudyDate);
info->m_StudyDate = std::string(StudyDate);
m_gdcmIO->GetStudyDate(Modality);
info->m_Modality = std::string(Modality);
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_WINDOW_LEVEL, s_wl);
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_WINDOW_WIDTH, s_ww);
itk::GDCMImageIO::GetLabelFromTag(USER_CONFIG::TAG_SERIES_NUMBER, info->lbl_ser_num);
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_SERIES_NUMBER, info->m_SeriesNumber);
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_SERIES_DESCRIPTION, info->m_SeriesDescription);
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_STUDY_TIME, info->m_StudyTime);
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_PATIANT_BIRTH, info->m_PatientBirth);
if (m_inputNames) { info->m_Institution = currentImageProperty->GetInstitutionName();
info->m_SliceNumber = to_string(m_inputNames->GetInputFileNames().size());
}
else
{
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_SLICE_NUM, info->m_SliceNumber);
}
m_gdcmIO->GetValueFromTag(USER_CONFIG::TAG_PATIENT_ORIENTATION,info->m_orientation); info->m_StudyDate = currentImageProperty->GetStudyDate();
info->WL = std::atoi(s_wl.c_str());
info->WW = std::atoi(s_ww.c_str()); info->m_Modality = currentImageProperty->GetModality();
info->lbl_ser_num = currentImageProperty->GetSeriesNumber();
info->m_SeriesNumber = currentImageProperty->GetSeriesNumber();
info->m_SeriesDescription = currentImageProperty->GetSeriesDescription();
info->m_StudyTime = currentImageProperty->GetStudyTime();
info->m_PatientBirth = currentImageProperty->GetPatientBirthDate();
char buffer[16]={0};
info->m_SliceNumber = itoa(currentImageProperty->GetFileNames()->size(), buffer,10);
info->m_orientation = "";
info->WL = currentImageProperty->GetNthWindowLevelPreset(0)[1];
info->WW = currentImageProperty->GetNthWindowLevelPreset(0)[0];
return info; return info;
} }

View File

@@ -0,0 +1,23 @@
//
// Created by Krad on 2022/2/10.
//
#include <vtkObjectFactory.h>
#include "ExtendMedicalImageProperties.h"
//----------------------------------------------------------------------------
vtkStandardNewMacro(ExtendMedicalImageProperties)
ExtendMedicalImageProperties::ExtendMedicalImageProperties() {
}
ExtendMedicalImageProperties::~ExtendMedicalImageProperties() {
}
void ExtendMedicalImageProperties::Clear() {
vtkMedicalImageProperties::Clear();
this->SetStudyUID(nullptr);
this->SetSeriesUID(nullptr);
}

View File

@@ -0,0 +1,70 @@
//
// Created by Krad on 2022/2/10.
//
#ifndef DCMV_EXTENDMEDICALIMAGEPROPERTIES_H
#define DCMV_EXTENDMEDICALIMAGEPROPERTIES_H
#include <vtkMedicalImageProperties.h>
#include <vector>
class ExtendMedicalImageProperties: public vtkMedicalImageProperties{
public:
static ExtendMedicalImageProperties *New();
vtkTypeMacro(ExtendMedicalImageProperties,vtkMedicalImageProperties);
/**
* Convenience method to reset all fields to an empty string/value
*/
void Clear() override;
vtkGetStringMacro(StudyUID)
vtkSetStringMacro(StudyUID)
vtkGetStringMacro(SeriesUID)
vtkSetStringMacro(SeriesUID)
vtkGetMacro(AcquisitionNumber, long)
vtkSetMacro(AcquisitionNumber, long)
vtkSetVector2Macro(Spacing,double);
vtkGetVector2Macro(Spacing,double);
std::vector<std::string>* GetFileNames(){
return &FileNames;
}
void SetFileNames(std::vector<std::string>& files){
FileNames = std::move(files);
}
long GetSeriesNumberAsLong(){
if (this->SeriesNumber){
return atol(this->SliceThickness);
}
return 0;
}
void SetSeriesNumber(long value){
char buffer [sizeof(long)*8+1];
this->SeriesNumber = ltoa(value, buffer, 10);
}
protected:
ExtendMedicalImageProperties();
~ExtendMedicalImageProperties() override;
char * StudyUID = nullptr;
char * SeriesUID = nullptr;
double Spacing[2] ={1.0,1.0};
long AcquisitionNumber = 0;
std::vector<std::string> FileNames;
private:
ExtendMedicalImageProperties(const ExtendMedicalImageProperties&) = delete;
void operator=(const ExtendMedicalImageProperties&) = delete;
};
#endif //DCMV_EXTENDMEDICALIMAGEPROPERTIES_H

View File

@@ -0,0 +1,114 @@
//
// Created by Krad on 2022/2/8.
//
#include "vtkDICOMImageReader2.h"
#include "vtkDataArray.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#include "DICOMAppHelper.h"
#include "DICOMParser.h"
vtkStandardNewMacro(vtkDICOMImageReader2);
vtkDICOMImageReader2::vtkDICOMImageReader2():vtkDICOMImageReader() {
}
vtkDICOMImageReader2::~vtkDICOMImageReader2() {
}
void vtkDICOMImageReader2::ExecuteInformation() {
vtkDICOMImageReader::ExecuteInformation();
if (!this->DirectoryName && !this->FileName && !DICOMFileNames->empty()){
//Sort files
std::vector<std::string>::iterator iter;
for (iter = this->DICOMFileNames->begin();
iter != this->DICOMFileNames->end();
++iter)
{
const char* fn = iter->c_str();
vtkDebugMacro( << "Trying : " << fn);
bool couldOpen = this->Parser->OpenFile(fn);
if (!couldOpen)
{
return;
}
//
this->Parser->ClearAllDICOMTagCallbacks();
this->AppHelper->RegisterCallbacks(this->Parser);
this->Parser->ReadHeader();
this->Parser->CloseFile();
vtkDebugMacro( << "File name : " << fn );
vtkDebugMacro( << "Slice number : " << this->AppHelper->GetSliceNumber());
}
std::vector<std::pair<float, std::string> > sortedFiles;
this->AppHelper->GetImagePositionPatientFilenamePairs(sortedFiles, false);
this->SetupOutputInformation(static_cast<int>(sortedFiles.size()));
//this->AppHelper->OutputSeries();
if (!sortedFiles.empty())
{
this->DICOMFileNames->clear();
std::vector<std::pair<float, std::string> >::iterator siter;
for (siter = sortedFiles.begin();
siter != sortedFiles.end();
++siter)
{
vtkDebugMacro(<< "Sorted filename : " << (*siter).second.c_str());
vtkDebugMacro(<< "Adding file " << (*siter).second.c_str() << " at slice : " << (*siter).first);
this->DICOMFileNames->push_back((*siter).second);
}
}
else
{
vtkErrorMacro( << "Couldn't get sorted files. Slices may be in wrong order!");
}
}
}
void vtkDICOMImageReader2::SetFileNames(const std::vector<std::string>& files) {
this->DICOMFileNames->clear();
this->AppHelper->Clear();
this->DirectoryName = nullptr;
this->FileName = nullptr;
for (vtkIdType i = 0; i < files.size(); i++)
{
if (strcmp(files[i].c_str(), ".") == 0 ||
strcmp(files[i].c_str(), "..") == 0)
{
continue;
}
std::string fileString = files[i];
int val = this->CanReadFile(fileString.c_str());
if (val == 1)
{
vtkDebugMacro( << "Adding " << fileString.c_str() << " to DICOMFileNames.");
this->DICOMFileNames->push_back(fileString);
}
else
{
vtkDebugMacro( << fileString.c_str() << " - DICOMParser CanReadFile returned : " << val);
}
}
}

View File

@@ -0,0 +1,51 @@
//
// Created by Krad on 2022/2/8.
//
#ifndef DCMV_VTKDICOMIMAGEREADER2_H
#define DCMV_VTKDICOMIMAGEREADER2_H
#include <vtkDICOMImageReader.h>
#include <vector>
#include <string>
class vtkDICOMImageReaderVector : public std::vector<std::string>
{
};
class vtkDICOMImageReader2: public vtkDICOMImageReader {
public:
//@{
/**
* Static method for construction.
*/
static vtkDICOMImageReader2 *New();
vtkTypeMacro(vtkDICOMImageReader2,vtkDICOMImageReader);
//@}
void SetFileNames(const std::vector<std::string>& files);
vtkDICOMImageReaderVector* GetDICOMFileNames(){
return DICOMFileNames;
}
protected:
void ExecuteInformation() override;
//
// Constructor
//
vtkDICOMImageReader2();
//
// Destructor
//
~vtkDICOMImageReader2() override;
private:
vtkDICOMImageReader2(const vtkDICOMImageReader2&) = delete;
void operator=(const vtkDICOMImageReader2&) = delete;
};
#endif //DCMV_VTKDICOMIMAGEREADER2_H

View File

@@ -31,7 +31,7 @@ void DicomExporter::execute(ExportOptions options)
{ {
for (int i = 0; i < exportOptions.inputData.size(); i++) for (int i = 0; i < exportOptions.inputData.size(); i++)
{ {
//Note<74><65>When the smart pointer points to another variable, it is automatically //Note<74><65>When the smart pointer points to another variable, it is automatically
//released, you can move it to outside or not. //released, you can move it to outside or not.
initDataReader(); initDataReader();
exportDicom(exportOptions.inputData.at(i)); exportDicom(exportOptions.inputData.at(i));
@@ -62,83 +62,83 @@ void DicomExporter::initVTK()
void DicomExporter::initDataReader() void DicomExporter::initDataReader()
{ {
m_gdcmIOExport = ImageIOTypeExport::New(); // m_gdcmIOExport = ImageIOTypeExport::New();
m_itkSeriesReaderExport = SeriesReaderTypeExport::New(); // m_itkSeriesReaderExport = SeriesReaderTypeExport::New();
m_itkSeriesReaderExport->SetImageIO(m_gdcmIOExport); // m_itkSeriesReaderExport->SetImageIO(m_gdcmIOExport);
m_itkConnectorExport = ConnectorTypeExport::New(); // m_itkConnectorExport = ConnectorTypeExport::New();
m_inputNamesExport = InputNamesGeneratorTypeExport::New(); // m_inputNamesExport = InputNamesGeneratorTypeExport::New();
} }
void DicomExporter::loadDicomFileAndRender(int file_type) void DicomExporter::loadDicomFileAndRender(int file_type)
{ {
try // try
{ // {
m_itkSeriesReaderExport->Update(); // m_itkSeriesReaderExport->Update();
} // }
catch (itk::ExceptionObject &excp) { // catch (itk::ExceptionObject &excp) {
std::cerr << "Exception thrown while reading the series" << std::endl; // std::cerr << "Exception thrown while reading the series" << std::endl;
std::cerr << excp << std::endl; // std::cerr << excp << std::endl;
} // }
//
m_itkConnectorExport->SetInput(m_itkSeriesReaderExport->GetOutput()); // m_itkConnectorExport->SetInput(m_itkSeriesReaderExport->GetOutput());
m_itkConnectorExport->Update(); // m_itkConnectorExport->Update();
//
m_imageViewerExport->SetInputData(m_itkConnectorExport->GetOutput()); // m_imageViewerExport->SetInputData(m_itkConnectorExport->GetOutput());
//
m_imageViewerExport->Render(); // m_imageViewerExport->Render();
m_imageViewerExport->SetSlice(0); // m_imageViewerExport->SetSlice(0);
//
//m_imageViewerExport->GetRenderer()->ResetCamera(); // //m_imageViewerExport->GetRenderer()->ResetCamera();
//
//
infinitiViewer *viewer = exportOptions.serie->getImageViewer2(); // infinitiViewer *viewer = exportOptions.serie->getImageViewer2();
//
if (exportOptions.windowLevel != -1) // if (exportOptions.windowLevel != -1)
{ // {
m_imageViewerExport->SetColorLevel(exportOptions.windowLevel); // m_imageViewerExport->SetColorLevel(exportOptions.windowLevel);
} // }
//
if (exportOptions.windowWidth != -1) // if (exportOptions.windowWidth != -1)
{ // {
m_imageViewerExport->SetColorWindow(exportOptions.windowWidth); // m_imageViewerExport->SetColorWindow(exportOptions.windowWidth);
} // }
//
if (exportOptions.cornerAnnotation != ExportOptions::CornerAnnotation::Disabled) // if (exportOptions.cornerAnnotation != ExportOptions::CornerAnnotation::Disabled)
{ // {
if (AnnoHelper::IsAnno()) { // if (AnnoHelper::IsAnno()) {
vtkCornerAnnotation* ann = m_imageViewerExport->GetvtkCornerAnnotation(); // vtkCornerAnnotation* ann = m_imageViewerExport->GetvtkCornerAnnotation();
ann->SetMaximumFontSize(20); // ann->SetMaximumFontSize(20);
ann->CopyAllTextsFrom(viewer->GetvtkCornerAnnotation()); // ann->CopyAllTextsFrom(viewer->GetvtkCornerAnnotation());
ann->SetText(BOTTOM_LEFT, ""); // ann->SetText(BOTTOM_LEFT, "");
//
std::string lbl_ser_num; // std::string lbl_ser_num;
std::string ser_num; // std::string ser_num;
itk::GDCMImageIO::GetLabelFromTag(USER_CONFIG::TAG_SERIES_NUMBER, lbl_ser_num); // itk::GDCMImageIO::GetLabelFromTag(USER_CONFIG::TAG_SERIES_NUMBER, lbl_ser_num);
m_gdcmIOExport->GetValueFromTag(USER_CONFIG::TAG_SERIES_NUMBER, ser_num); // m_gdcmIOExport->GetValueFromTag(USER_CONFIG::TAG_SERIES_NUMBER, ser_num);
m_imageViewerExport->initTopLeftCornerInfo(lbl_ser_num, ser_num); // m_imageViewerExport->initTopLeftCornerInfo(lbl_ser_num, ser_num);
} // }
} // }
//
//
double vup[3]; // double vup[3];
double vup2[3]; // double vup2[3];
vtkCamera *oriCamera = viewer->GetRenderer()->GetActiveCamera(); // vtkCamera *oriCamera = viewer->GetRenderer()->GetActiveCamera();
double scale = exportOptions.serie->GetExtent(); // double scale = exportOptions.serie->GetExtent();
oriCamera->GetViewUp(vup); // oriCamera->GetViewUp(vup);
//
vtkCamera *expCamera = m_imageViewerExport->GetRenderer()->GetActiveCamera(); // vtkCamera *expCamera = m_imageViewerExport->GetRenderer()->GetActiveCamera();
expCamera->SetParallelScale(scale); // expCamera->SetParallelScale(scale);
expCamera->GetViewUp(vup2); // expCamera->GetViewUp(vup2);
expCamera->SetViewUp(vup); // expCamera->SetViewUp(vup);
//
if (FlipExportHelper::GetFlip()) // if (FlipExportHelper::GetFlip())
{ // {
expCamera->Azimuth(180); // expCamera->Azimuth(180);
m_imageViewerExport->GetRenderer()->ResetCameraClippingRange(); // m_imageViewerExport->GetRenderer()->ResetCameraClippingRange();
//
} // }
m_imageViewerExport->GetRenderWindow()->Render(); // m_imageViewerExport->GetRenderWindow()->Render();
} }
@@ -291,187 +291,187 @@ void DicomExporter::writeToTiffFile(vtkSmartPointer<vtkWindowToImageFilter> wind
void DicomExporter::exportPicture(const QString& fileName) void DicomExporter::exportPicture(const QString& fileName)
{ {
int myFileType = NonType; // int myFileType = NonType;
//
QFileInfo fileInfo(fileName); // QFileInfo fileInfo(fileName);
QDir dir(fileName); // QDir dir(fileName);
//
if (fileInfo.isFile()) // if (fileInfo.isFile())
{ // {
m_itkSeriesReaderExport->SetFileName(fileName.toStdString()); // m_itkSeriesReaderExport->SetFileName(fileName.toStdString());
//
myFileType = SingleFile; // myFileType = SingleFile;
} // }
else if (dir.exists()) // else if (dir.exists())
{ // {
m_inputNamesExport->SetInputDirectory(fileName.toStdString()); // m_inputNamesExport->SetInputDirectory(fileName.toStdString());
const SeriesReaderTypeExport::FileNamesContainer & filenames = m_inputNamesExport->GetInputFileNames(); // const SeriesReaderTypeExport::FileNamesContainer & filenames = m_inputNamesExport->GetInputFileNames();
m_itkSeriesReaderExport->SetFileNames(filenames); // m_itkSeriesReaderExport->SetFileNames(filenames);
//
myFileType = DirType; // myFileType = DirType;
} // }
//
if (myFileType != NonType) // if (myFileType != NonType)
{ // {
loadDicomFileAndRender(myFileType); // loadDicomFileAndRender(myFileType);
doExport(myFileType); // doExport(myFileType);
} // }
} }
void DicomExporter::exportDicom(const QString& fileName) void DicomExporter::exportDicom(const QString& fileName)
{ {
bool isFileValid = false; // bool isFileValid = false;
//
QFileInfo fileInfo(fileName); // QFileInfo fileInfo(fileName);
QDir dir(fileName); // QDir dir(fileName);
//
if (fileInfo.isFile()) // if (fileInfo.isFile())
{ // {
m_itkSeriesReaderExport->SetFileName(fileName.toStdString()); // m_itkSeriesReaderExport->SetFileName(fileName.toStdString());
//
exportSingleDicomFile(fileName); // exportSingleDicomFile(fileName);
} // }
else if (dir.exists()) // else if (dir.exists())
{ // {
m_inputNamesExport->SetInputDirectory(fileName.toStdString()); // m_inputNamesExport->SetInputDirectory(fileName.toStdString());
const SeriesReaderTypeExport::FileNamesContainer & filenames = m_inputNamesExport->GetInputFileNames(); // const SeriesReaderTypeExport::FileNamesContainer & filenames = m_inputNamesExport->GetInputFileNames();
m_itkSeriesReaderExport->SetFileNames(filenames); // m_itkSeriesReaderExport->SetFileNames(filenames);
//
exportDicomDirectory(fileName); // exportDicomDirectory(fileName);
} // }
} }
void DicomExporter::exportSingleDicomFile(const QString& fileName) void DicomExporter::exportSingleDicomFile(const QString& fileName)
{ {
try // try
{ // {
m_itkSeriesReaderExport->UpdateLargestPossibleRegion(); // m_itkSeriesReaderExport->UpdateLargestPossibleRegion();
m_itkSeriesReaderExport->Update(); // m_itkSeriesReaderExport->Update();
} // }
catch (itk::ExceptionObject &excp) { // catch (itk::ExceptionObject &excp) {
std::cerr << "Exception thrown while reading the series" << std::endl; // std::cerr << "Exception thrown while reading the series" << std::endl;
std::cerr << excp << std::endl; // std::cerr << excp << std::endl;
} // }
//
exportedNumber++;//image number starts from 1 // exportedNumber++;//image number starts from 1
QString exportedName = exportOptions.exportDirectory + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm"; // QString exportedName = exportOptions.exportDirectory + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm";
QByteArray bafileName = exportedName.toLocal8Bit(); // QByteArray bafileName = exportedName.toLocal8Bit();
//
//
SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New(); // SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
seriesWriter->SetImageIO(m_gdcmIOExport); // seriesWriter->SetImageIO(m_gdcmIOExport);
seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput()); // seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput());
seriesWriter->SetFileName(std::string(bafileName)); // seriesWriter->SetFileName(std::string(bafileName));
//
SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray(); // SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray();
modifyDicomTags(dicArray); // modifyDicomTags(dicArray);
seriesWriter->SetMetaDataDictionaryArray(dicArray); // seriesWriter->SetMetaDataDictionaryArray(dicArray);
//
try // try
{ // {
seriesWriter->Update(); // seriesWriter->Update();
//
emit exportProgress(totalCount, exportedNumber); // emit exportProgress(totalCount, exportedNumber);
} // }
catch (itk::ExceptionObject & excp) // catch (itk::ExceptionObject & excp)
{ // {
std::cerr << "Exception thrown while writing the series " << std::endl; // std::cerr << "Exception thrown while writing the series " << std::endl;
std::cerr << excp << std::endl; // std::cerr << excp << std::endl;
} // }
} }
void DicomExporter::exportDicomDirectory(const QString& fileName) void DicomExporter::exportDicomDirectory(const QString& fileName)
{ {
try // try
{ // {
m_itkSeriesReaderExport->Update(); // m_itkSeriesReaderExport->Update();
} // }
catch (itk::ExceptionObject &excp) { // catch (itk::ExceptionObject &excp) {
std::cerr << "Exception thrown while reading the series" << std::endl; // std::cerr << "Exception thrown while reading the series" << std::endl;
std::cerr << excp << std::endl; // std::cerr << excp << std::endl;
} // }
//
m_inputNamesExport->SetOutputDirectory(exportOptions.exportDirectory.toStdString()); // m_inputNamesExport->SetOutputDirectory(exportOptions.exportDirectory.toStdString());
//
itk::SerieUIDContainer newOutNames; // itk::SerieUIDContainer newOutNames;
itk::SerieUIDContainer oldOutputNames = m_inputNamesExport->GetOutputFileNames(); // itk::SerieUIDContainer oldOutputNames = m_inputNamesExport->GetOutputFileNames();
for (int i = 0; i < oldOutputNames.size(); i++) // for (int i = 0; i < oldOutputNames.size(); i++)
{ // {
std::string originName = oldOutputNames.at(i); // std::string originName = oldOutputNames.at(i);
QFileInfo fileinfo(QString::fromStdString(originName)); // QFileInfo fileinfo(QString::fromStdString(originName));
QString fName = fileinfo.fileName(); // QString fName = fileinfo.fileName();
QString fPath = fileinfo.absolutePath(); // QString fPath = fileinfo.absolutePath();
//
exportedNumber++;//image number starts from 1 // exportedNumber++;//image number starts from 1
QString newName = fPath + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm"; // QString newName = fPath + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm";
QByteArray bafileName = newName.toLocal8Bit(); // QByteArray bafileName = newName.toLocal8Bit();
//
newOutNames.push_back(std::string(bafileName)); // newOutNames.push_back(std::string(bafileName));
} // }
//
SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New(); // SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
seriesWriter->SetImageIO(m_gdcmIOExport); // seriesWriter->SetImageIO(m_gdcmIOExport);
seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput()); // seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput());
seriesWriter->SetFileNames(newOutNames); // seriesWriter->SetFileNames(newOutNames);
//
SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray(); // SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray();
modifyDicomTags(dicArray); // modifyDicomTags(dicArray);
seriesWriter->SetMetaDataDictionaryArray(dicArray); // seriesWriter->SetMetaDataDictionaryArray(dicArray);
//
try // try
{ // {
emit exportProgress(totalCount, exportedNumber / 2); // emit exportProgress(totalCount, exportedNumber / 2);
//
seriesWriter->Update(); // seriesWriter->Update();
//
emit exportProgress(totalCount, exportedNumber); // emit exportProgress(totalCount, exportedNumber);
} // }
catch (itk::ExceptionObject & excp) // catch (itk::ExceptionObject & excp)
{ // {
std::cerr << "Exception thrown while writing the series " << std::endl; // std::cerr << "Exception thrown while writing the series " << std::endl;
std::cerr << excp << std::endl; // std::cerr << excp << std::endl;
} // }
} }
void DicomExporter::modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray) //void DicomExporter::modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray)
{ //{
for (int i = 0; i < (*dicArray).size(); i++) // for (int i = 0; i < (*dicArray).size(); i++)
{ // {
itk::MetaDataDictionary *dic = (*dicArray).at(i); // itk::MetaDataDictionary *dic = (*dicArray).at(i);
//
if (exportOptions.windowLevel != -1) // if (exportOptions.windowLevel != -1)
{ // {
std::string entryId(TAG_WindowLevel); // std::string entryId(TAG_WindowLevel);
itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowLevel)); // itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowLevel));
} // }
//
if (exportOptions.windowWidth != -1) // if (exportOptions.windowWidth != -1)
{ // {
std::string entryId(TAG_WindowWidth); // std::string entryId(TAG_WindowWidth);
itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowWidth)); // itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowWidth));
} // }
//
if (exportOptions.isAnonymization) // if (exportOptions.isAnonymization)
{ // {
itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionName, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionName, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionAddress, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionAddress, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_ReferringPhysicianName, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_ReferringPhysicianName, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_OperatorsName, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_OperatorsName, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAddress, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAddress, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientTelephoneNumbers, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientTelephoneNumbers, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientNames, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientNames, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDs, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDs, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDsSequence, ""); // itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDsSequence, "");
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientName, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientName, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientBirthDate, "19000101"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientBirthDate, "19000101");
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientSex, "NA"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientSex, "NA");
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAge, "NA"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAge, "NA");
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientID, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientID, "anonymized");
itk::EncapsulateMetaData<std::string>(*dic, TAG_AccessionNumber, "anonymized"); // itk::EncapsulateMetaData<std::string>(*dic, TAG_AccessionNumber, "anonymized");
} // }
//
}//for end // }//for end
} //}
void DicomExporter::caculateExportTotalCount() void DicomExporter::caculateExportTotalCount()
{ {