feat: Add more Study Information to dicom export

This commit is contained in:
kradchen
2024-09-19 15:35:43 +08:00
parent a8356cd258
commit 658782b96d
3 changed files with 76 additions and 51 deletions

View File

@@ -20,57 +20,57 @@ namespace {
return (endPoint[index]-startPoint[index])/(float)(imageXYZ[index])*1000.0; return (endPoint[index]-startPoint[index])/(float)(imageXYZ[index])*1000.0;
} }
void initialDicomFile(DcmDataset* dataset,DcmMetaInfo* metaInfo) void initialDicomFile(DcmDataset* aDataset,DcmMetaInfo* aMetaInfo)
{ {
metaInfo->putAndInsertString(DCM_MediaStorageSOPClassUID, aMetaInfo->putAndInsertString(DCM_MediaStorageSOPClassUID,
UID_CTImageStorage); UID_CTImageStorage);
dataset->putAndInsertString(DCM_SOPClassUID, UID_CTImageStorage); aDataset->putAndInsertString(DCM_SOPClassUID, UID_CTImageStorage);
dataset->putAndInsertString(DCM_Modality, "CT"); aDataset->putAndInsertString(DCM_Modality, "CT");
dataset->putAndInsertString(DCM_TransferSyntaxUID, aDataset->putAndInsertString(DCM_TransferSyntaxUID,
UID_LittleEndianImplicitTransferSyntax); UID_LittleEndianImplicitTransferSyntax);
dataset->putAndInsertString(DCM_ImageType, "ORIGINAL\\PRIMARY"); aDataset->putAndInsertString(DCM_ImageType, "ORIGINAL\\PRIMARY");
dataset->putAndInsertString(DCM_Manufacturer, "EQ9"); aDataset->putAndInsertString(DCM_Manufacturer, "EQ9");
dataset->putAndInsertString(DCM_PatientOrientation, "L\\H"); aDataset->putAndInsertString(DCM_PatientOrientation, "L\\H");
dataset->putAndInsertString(DCM_PatientPosition, "HFP"); aDataset->putAndInsertString(DCM_PatientPosition, "HFP");
dataset->putAndInsertString(DCM_ImageOrientationPatient, "1\\0\\0\\0\\0\\1"); aDataset->putAndInsertString(DCM_ImageOrientationPatient, "1\\0\\0\\0\\0\\1");
dataset->putAndInsertString(DCM_StudyDescription, "USCT BREAST"); aDataset->putAndInsertString(DCM_StudyDescription, "USCT BREAST");
dataset->putAndInsertString(DCM_ManufacturerModelVersion, "USCT3DV3"); aDataset->putAndInsertString(DCM_ManufacturerModelVersion, "USCT3DV3");
dataset->putAndInsertString(DCM_SamplesPerPixel, "1"); aDataset->putAndInsertString(DCM_SamplesPerPixel, "1");
dataset->putAndInsertString(DCM_PixelRepresentation, "0"); aDataset->putAndInsertString(DCM_PixelRepresentation, "0");
dataset->putAndInsertString(DCM_BitsAllocated, "16"); aDataset->putAndInsertString(DCM_BitsAllocated, "16");
dataset->putAndInsertString(DCM_BitsStored, "16"); aDataset->putAndInsertString(DCM_BitsStored, "16");
dataset->putAndInsertString(DCM_HighBit, "15"); aDataset->putAndInsertString(DCM_HighBit, "15");
dataset->putAndInsertString(DCM_PhotometricInterpretation, "MONOCHROME2"); aDataset->putAndInsertString(DCM_PhotometricInterpretation, "MONOCHROME2");
dataset->putAndInsertString(DCM_KVP, "0"); aDataset->putAndInsertString(DCM_KVP, "0");
} }
void initialDate(DcmDataset* dataset,const std::string& mStudyDate ) void initialDate(DcmDataset* aDataset,const std::string& aStudyDate )
{ {
dataset->putAndInsertString(DCM_StudyDate, mStudyDate.data()); aDataset->putAndInsertString(DCM_StudyDate, aStudyDate.data());
OFDateTime currentDateTime; OFDateTime currentDateTime;
currentDateTime.setCurrentDateTime(); currentDateTime.setCurrentDateTime();
OFString date; OFString date;
currentDateTime.getDate().getISOFormattedDate(date,false); currentDateTime.getDate().getISOFormattedDate(date,false);
dataset->putAndInsertString(DCM_SeriesDate, date.data()); aDataset->putAndInsertString(DCM_SeriesDate, aStudyDate.data());
dataset->putAndInsertString(DCM_AcquisitionDate, date.data()); aDataset->putAndInsertString(DCM_AcquisitionDate, aStudyDate.data());
dataset->putAndInsertString(DCM_ContentDate, date.data()); aDataset->putAndInsertString(DCM_ContentDate, date.data());
} }
void initialSeriesTime(DcmDataset* dataset){ void initialSeriesTime(DcmDataset* aDataset,const std::string& aStudyTime){
// 获取当前日期和时间UTC时间 // 获取当前日期和时间UTC时间
OFDateTime currentDateTime; OFDateTime currentDateTime;
currentDateTime.setCurrentDateTime(); currentDateTime.setCurrentDateTime();
OFString time; OFString time;
currentDateTime.getTime().getISOFormattedTime(time,true,false,false,false); currentDateTime.getTime().getISOFormattedTime(time,true,false,false,false);
dataset->putAndInsertString(DCM_SeriesTime, time.data()); aDataset->putAndInsertString(DCM_SeriesTime, aStudyTime.data());
dataset->putAndInsertString(DCM_AcquisitionTime, time.data()); aDataset->putAndInsertString(DCM_AcquisitionTime, aStudyTime.data());
dataset->putAndInsertString(DCM_ContentTime, time.data()); aDataset->putAndInsertString(DCM_ContentTime, time.data());
} }
const char* SeriesDescriptions[3]={"REFL","SOS","ATT"}; const char* SeriesDescriptions[3]={"REFL","SOS","ATT"};
const char* getSeriesDescription(int type){ const char* getSeriesDescription(int type){
@@ -81,26 +81,49 @@ namespace {
namespace Recon namespace Recon
{ {
DICOMExporter::DICOMExporter(const PatientData& aPatientData) DICOMExporter::DICOMExporter(const PatientData& aPatientData, const MetaData& aMetaData)
{ {
mPatientData = aPatientData; mPatientData = aPatientData;
//prepare Study //prepare Study
dcmGenerateUniqueIdentifier(mStudyInstanceUID,SITE_STUDY_UID_ROOT); if (aPatientData.getStudyUID().empty()){
char tempStr [100] = {0};
dcmGenerateUniqueIdentifier(tempStr,SITE_STUDY_UID_ROOT);
mStudyInstanceUID.append(tempStr);
}
else{
mStudyInstanceUID = aPatientData.getStudyUID();
}
std::string measurementID = aMetaData.getMeasurementID();
unsigned long dateIndex = measurementID.find('_');
unsigned long timeIndex = measurementID.find('T');
OFDateTime currentDateTime; OFDateTime currentDateTime;
currentDateTime.setCurrentDateTime(); currentDateTime.setCurrentDateTime();
OFString date; if(dateIndex== std::string::npos || measurementID.length()-dateIndex<=8){
currentDateTime.getDate().getISOFormattedDate(date,false);
OFString time; OFString date;
currentDateTime.getTime().getISOFormattedTime(time,true,false,false,false); currentDateTime.getDate().getISOFormattedDate(date,false);
mStudyDate = date.data(); mStudyDate = date.data();
mStudyTime = time.data();
}
else{
mStudyDate = measurementID.substr(dateIndex+1,8);
}
if(timeIndex== std::string::npos || measurementID.length()-timeIndex<=6){
OFString time;
currentDateTime.getTime().getISOFormattedTime(time,true,false,false,false);
mStudyTime = time.data();
}
else{
mStudyTime = measurementID.substr(timeIndex+1,6);
}
} }
DICOMExporter::DICOMExporter() DICOMExporter::DICOMExporter()
{ {
//prepare Study //prepare Study
dcmGenerateUniqueIdentifier(mStudyInstanceUID,SITE_STUDY_UID_ROOT); char tempStr [100] = {0};
dcmGenerateUniqueIdentifier(tempStr,SITE_STUDY_UID_ROOT);
mStudyInstanceUID.append(tempStr);
OFDateTime currentDateTime; OFDateTime currentDateTime;
currentDateTime.setCurrentDateTime(); currentDateTime.setCurrentDateTime();
@@ -141,8 +164,9 @@ namespace Recon
DcmMetaInfo* metaInfo = dcmFile.getMetaInfo(); DcmMetaInfo* metaInfo = dcmFile.getMetaInfo();
initialDicomFile(dataset,metaInfo); initialDicomFile(dataset,metaInfo);
dataset->putAndInsertString(DCM_SpecificCharacterSet, "ISO_IR 192");
dataset->putAndInsertString(DCM_StudyInstanceUID, mStudyInstanceUID); dataset->putAndInsertString(DCM_StudyInstanceUID, mStudyInstanceUID.data());
dcmGenerateUniqueIdentifier(mSeriesInstanceUID,SITE_SERIES_UID_ROOT); dcmGenerateUniqueIdentifier(mSeriesInstanceUID,SITE_SERIES_UID_ROOT);
dataset->putAndInsertString(DCM_SeriesInstanceUID, mSeriesInstanceUID); dataset->putAndInsertString(DCM_SeriesInstanceUID, mSeriesInstanceUID);
@@ -152,7 +176,7 @@ namespace Recon
dataset->putAndInsertString(DCM_StudyTime, mStudyTime.data()); dataset->putAndInsertString(DCM_StudyTime, mStudyTime.data());
::initialSeriesTime(dataset); ::initialSeriesTime(dataset, mStudyTime);
dataset->putAndInsertString(DCM_InstitutionName, mPatientData.getInstituationName().empty()? dataset->putAndInsertString(DCM_InstitutionName, mPatientData.getInstituationName().empty()?
"InstName":mPatientData.getInstituationName().data()); "InstName":mPatientData.getInstituationName().data());
@@ -168,7 +192,7 @@ namespace Recon
"TestPatID":mPatientData.getPatientID().data()); "TestPatID":mPatientData.getPatientID().data());
dataset->putAndInsertString(DCM_Laterality, mPatientData.getLaterality().data()); dataset->putAndInsertString(DCM_Laterality, mPatientData.getLaterality().data());
dataset->putAndInsertString(DCM_StudyID, "0"); dataset->putAndInsertString(DCM_StudyID, mStudyTime.data());
dataset->putAndInsertString(DCM_SeriesNumber, to_string(type).data()); dataset->putAndInsertString(DCM_SeriesNumber, to_string(type).data());
dataset->putAndInsertString(DCM_SeriesDescription, ::getSeriesDescription(type)); dataset->putAndInsertString(DCM_SeriesDescription, ::getSeriesDescription(type));
// dataset->putAndInsertString(DCM_ProtocolName, "?"); // dataset->putAndInsertString(DCM_ProtocolName, "?");
@@ -227,7 +251,7 @@ namespace Recon
size_t sliceSize = Rows*Cols; size_t sliceSize = Rows*Cols;
for (size_t i = 0; i < Slices; i++) for (size_t i = 0; i < Slices; i++)
{ {
dataset->putAndInsertString(DCM_AccessionNumber, to_string(i).data()); dataset->putAndInsertString(DCM_AccessionNumber, mPatientData.getAccessionNumber().data());
dataset->putAndInsertString(DCM_InstanceNumber, to_string(i).data()); dataset->putAndInsertString(DCM_InstanceNumber, to_string(i).data());
string pos = to_string(originPosition[1] ) + "\\" + string pos = to_string(originPosition[1] ) + "\\" +
to_string(originPosition[2]+ i * spacing[2]) + "\\" + to_string(originPosition[2]+ i * spacing[2]) + "\\" +

View File

@@ -5,6 +5,8 @@
#include "Matrix.h" #include "Matrix.h"
#include "Parser/Data/PatientData.h" #include "Parser/Data/PatientData.h"
#include "Parser/Data/MetaData.h"
namespace Recon { namespace Recon {
class DICOMExporter class DICOMExporter
@@ -15,7 +17,7 @@ public:
SOS, SOS,
ATT ATT
}; };
explicit DICOMExporter(const PatientData& aPatientData); explicit DICOMExporter(const PatientData& aPatientData, const MetaData& aMetaData);
//仅仅用于测试!!! //仅仅用于测试!!!
DICOMExporter(); DICOMExporter();
DICOMExporter(DICOMExporter &&) = default; DICOMExporter(DICOMExporter &&) = default;
@@ -29,8 +31,7 @@ private:
std::string mBasePath; std::string mBasePath;
std::string mStudyDate; std::string mStudyDate;
std::string mStudyTime; std::string mStudyTime;
std::string mStudyInstanceUID;
char mStudyInstanceUID[100]={0};
char mSeriesInstanceUID[100]={0}; char mSeriesInstanceUID[100]={0};
PatientData mPatientData; PatientData mPatientData;
void exportDCM(std::string path, float * startPoint, float* endPoint, int* imageXYZ,float* data, int type); void exportDCM(std::string path, float * startPoint, float* endPoint, int* imageXYZ,float* data, int type);

View File

@@ -31,12 +31,12 @@
using namespace Recon; using namespace Recon;
using namespace Aurora; using namespace Aurora;
int Recon::startReconstructions(const std::string& aDataPath, const std::string& aDataRefPath, const std::string& aOutputPath) int Recon::startReconstructions( const std::string& aDataPath, const std::string& aDataRefPath, const std::string& aOutputPath)
{ {
MatlabWriter writer(aOutputPath); // MatlabWriter writer(aOutputPath);
Parser dataParser(aDataPath); Parser dataParser(aDataPath);
Parser refParser(aDataRefPath); Parser refParser(aDataRefPath);
Recon::DICOMExporter exporter(dataParser.getPatientData()); Recon::DICOMExporter exporter(dataParser.getPatientData(), dataParser.getMetaData());
exporter.setExportBasePath(aOutputPath); exporter.setExportBasePath(aOutputPath);
if(!dataParser.getShotList()->isValid()) if(!dataParser.getShotList()->isValid())
{ {
@@ -255,9 +255,9 @@ int Recon::startReconstructions(const std::string& aDataPath, const std::string&
//Recon::notifyProgress(25); //Recon::notifyProgress(25);
RECON_INFO("Start reflectionRecostruction."); RECON_INFO("Start reflectionRecostruction.");
Matrix env = startReflectionReconstruction(&dataParser, preProcessData.saftMode, mp_inter, slList_inter, snList_inter, rlList_inter, rnList_inter, geom, preProcessData.transRecos, expInfo, preComputes); Matrix env = startReflectionReconstruction(&dataParser, preProcessData.saftMode, mp_inter, slList_inter, snList_inter, rlList_inter, rnList_inter, geom, preProcessData.transRecos, expInfo, preComputes);
writer.setMatrix(env, "reflect"); // writer.setMatrix(env, "reflect");
exporter.exportDICOM(env, Recon::DICOMExporter::REFL); exporter.exportDICOM(env, Recon::DICOMExporter::REFL);
// Recon::notifyProgress(99); //Recon::notifyProgress(99);
} }
// writer.write(); // writer.write();
return 0; return 0;