Remove ITK, use simple DICOM image reader read DICOM files.
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
175
src/src/base/DICOMDirectoryHelper.cpp
Normal file
175
src/src/base/DICOMDirectoryHelper.cpp
Normal 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;
|
||||||
|
}
|
||||||
56
src/src/base/DICOMDirectoryHelper.h
Normal file
56
src/src/base/DICOMDirectoryHelper.h
Normal 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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
src/src/base/ExtendMedicalImageProperties.cpp
Normal file
23
src/src/base/ExtendMedicalImageProperties.cpp
Normal 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);
|
||||||
|
}
|
||||||
70
src/src/base/ExtendMedicalImageProperties.h
Normal file
70
src/src/base/ExtendMedicalImageProperties.h
Normal 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
|
||||||
114
src/src/base/vtkDICOMImageReader2.cpp
Normal file
114
src/src/base/vtkDICOMImageReader2.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/src/base/vtkDICOMImageReader2.h
Normal file
51
src/src/base/vtkDICOMImageReader2.h
Normal 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
|
||||||
@@ -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());
|
||||||
|
//
|
||||||
|
// itk::SerieUIDContainer newOutNames;
|
||||||
|
// itk::SerieUIDContainer oldOutputNames = m_inputNamesExport->GetOutputFileNames();
|
||||||
|
// for (int i = 0; i < oldOutputNames.size(); i++)
|
||||||
|
// {
|
||||||
|
// std::string originName = oldOutputNames.at(i);
|
||||||
|
// QFileInfo fileinfo(QString::fromStdString(originName));
|
||||||
|
// QString fName = fileinfo.fileName();
|
||||||
|
// QString fPath = fileinfo.absolutePath();
|
||||||
|
//
|
||||||
|
// exportedNumber++;//image number starts from 1
|
||||||
|
// QString newName = fPath + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm";
|
||||||
|
// QByteArray bafileName = newName.toLocal8Bit();
|
||||||
|
//
|
||||||
|
// newOutNames.push_back(std::string(bafileName));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
|
||||||
|
// seriesWriter->SetImageIO(m_gdcmIOExport);
|
||||||
|
// seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput());
|
||||||
|
// seriesWriter->SetFileNames(newOutNames);
|
||||||
|
//
|
||||||
|
// SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray();
|
||||||
|
// modifyDicomTags(dicArray);
|
||||||
|
// seriesWriter->SetMetaDataDictionaryArray(dicArray);
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// emit exportProgress(totalCount, exportedNumber / 2);
|
||||||
|
//
|
||||||
|
// seriesWriter->Update();
|
||||||
|
//
|
||||||
|
// emit exportProgress(totalCount, exportedNumber);
|
||||||
|
// }
|
||||||
|
// catch (itk::ExceptionObject & excp)
|
||||||
|
// {
|
||||||
|
// std::cerr << "Exception thrown while writing the series " << std::endl;
|
||||||
|
// std::cerr << excp << std::endl;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inputNamesExport->SetOutputDirectory(exportOptions.exportDirectory.toStdString());
|
//void DicomExporter::modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray)
|
||||||
|
//{
|
||||||
itk::SerieUIDContainer newOutNames;
|
// for (int i = 0; i < (*dicArray).size(); i++)
|
||||||
itk::SerieUIDContainer oldOutputNames = m_inputNamesExport->GetOutputFileNames();
|
// {
|
||||||
for (int i = 0; i < oldOutputNames.size(); i++)
|
// itk::MetaDataDictionary *dic = (*dicArray).at(i);
|
||||||
{
|
//
|
||||||
std::string originName = oldOutputNames.at(i);
|
// if (exportOptions.windowLevel != -1)
|
||||||
QFileInfo fileinfo(QString::fromStdString(originName));
|
// {
|
||||||
QString fName = fileinfo.fileName();
|
// std::string entryId(TAG_WindowLevel);
|
||||||
QString fPath = fileinfo.absolutePath();
|
// itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowLevel));
|
||||||
|
// }
|
||||||
exportedNumber++;//image number starts from 1
|
//
|
||||||
QString newName = fPath + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm";
|
// if (exportOptions.windowWidth != -1)
|
||||||
QByteArray bafileName = newName.toLocal8Bit();
|
// {
|
||||||
|
// std::string entryId(TAG_WindowWidth);
|
||||||
newOutNames.push_back(std::string(bafileName));
|
// itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowWidth));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
|
// if (exportOptions.isAnonymization)
|
||||||
seriesWriter->SetImageIO(m_gdcmIOExport);
|
// {
|
||||||
seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput());
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionName, "anonymized");
|
||||||
seriesWriter->SetFileNames(newOutNames);
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionAddress, "anonymized");
|
||||||
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_ReferringPhysicianName, "anonymized");
|
||||||
SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray();
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OperatorsName, "anonymized");
|
||||||
modifyDicomTags(dicArray);
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAddress, "anonymized");
|
||||||
seriesWriter->SetMetaDataDictionaryArray(dicArray);
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientTelephoneNumbers, "anonymized");
|
||||||
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientNames, "anonymized");
|
||||||
try
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDs, "anonymized");
|
||||||
{
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDsSequence, "");
|
||||||
emit exportProgress(totalCount, exportedNumber / 2);
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientName, "anonymized");
|
||||||
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientBirthDate, "19000101");
|
||||||
seriesWriter->Update();
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientSex, "NA");
|
||||||
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAge, "NA");
|
||||||
emit exportProgress(totalCount, exportedNumber);
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientID, "anonymized");
|
||||||
}
|
// itk::EncapsulateMetaData<std::string>(*dic, TAG_AccessionNumber, "anonymized");
|
||||||
catch (itk::ExceptionObject & excp)
|
// }
|
||||||
{
|
//
|
||||||
std::cerr << "Exception thrown while writing the series " << std::endl;
|
// }//for end
|
||||||
std::cerr << excp << std::endl;
|
//}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < (*dicArray).size(); i++)
|
|
||||||
{
|
|
||||||
itk::MetaDataDictionary *dic = (*dicArray).at(i);
|
|
||||||
|
|
||||||
if (exportOptions.windowLevel != -1)
|
|
||||||
{
|
|
||||||
std::string entryId(TAG_WindowLevel);
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowLevel));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exportOptions.windowWidth != -1)
|
|
||||||
{
|
|
||||||
std::string entryId(TAG_WindowWidth);
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowWidth));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exportOptions.isAnonymization)
|
|
||||||
{
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionName, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionAddress, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_ReferringPhysicianName, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_OperatorsName, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAddress, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientTelephoneNumbers, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientNames, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDs, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDsSequence, "");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientName, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientBirthDate, "19000101");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientSex, "NA");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAge, "NA");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientID, "anonymized");
|
|
||||||
itk::EncapsulateMetaData<std::string>(*dic, TAG_AccessionNumber, "anonymized");
|
|
||||||
}
|
|
||||||
|
|
||||||
}//for end
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::caculateExportTotalCount()
|
void DicomExporter::caculateExportTotalCount()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user