From 258b56b456be7fbf66becebe13db156c086042c2 Mon Sep 17 00:00:00 2001 From: Krad Date: Thu, 15 Sep 2022 11:04:21 +0800 Subject: [PATCH] Simple overlay load. --- src/src/IO/DICOM/DICOMPixelDataHelper.cpp | 33 +++++++++++++++++-- src/src/IO/DICOM/DICOMPixelDataHelper.h | 1 + .../IO/DICOM/ExtendMedicalImageProperties.h | 4 +++ src/src/IO/DICOM/vtkDICOMImageReader2.cpp | 23 +++++++++++++ src/src/IO/DICOM/vtkDICOMImageReader2.h | 10 +++++- 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/src/IO/DICOM/DICOMPixelDataHelper.cpp b/src/src/IO/DICOM/DICOMPixelDataHelper.cpp index 9625599..ebf6eda 100644 --- a/src/src/IO/DICOM/DICOMPixelDataHelper.cpp +++ b/src/src/IO/DICOM/DICOMPixelDataHelper.cpp @@ -154,6 +154,17 @@ void DICOMPixelDataHelper::GetRGBPixelData(const char *path, void *data, unsigne delete fileFormat; } +int DICOMPixelDataHelper::GetOverLayCount(const char *path) { + int ret = 0; + DcmFileFormat fileFormat; + if (fileFormat.loadFile(path).good()) { + DcmDataset * dset = fileFormat.getDataset(); + DicomImage dcmImage(&fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData); + ret = dcmImage.getOverlayCount(); + } + return ret; +} + void DICOMPixelDataHelper::GetOverlayData(const char *path, void *data, unsigned int& width, unsigned int& height, unsigned int plane) { DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法 @@ -163,8 +174,26 @@ void DICOMPixelDataHelper::GetOverlayData(const char *path, void *data, if(dcmImage.getOverlayCount()>plane){ const void * overlay = dcmImage.getFullOverlayData(plane,width, height); int dataLength = width*height; - data = new unsigned char[dataLength]; - memcpy(data, overlay,dataLength); + if (plane == 0){ + memcpy(data, overlay, dataLength); + } + else{ + int count32 = dataLength / 4; + int tailCount8 = dataLength % 4; + //OR operation header and content + Uint32 * mergeDst = (Uint32*)data; + Uint32 * mergeSrc = (Uint32*)overlay; + for (int i = 0; i < count32; ++i) { + mergeDst[i] = mergeDst[i] | mergeSrc[i]; + } + //OR operation tail + Uint8 * mergeDst8 = (Uint8*)data; + Uint8 * mergeSrc8 = (Uint8*)overlay; + for (int i = 1; i <= tailCount8; ++i) { + mergeDst8[dataLength - i] = mergeDst8[dataLength - i] | mergeSrc8[dataLength - i]; + } + } + dcmImage.deleteOverlayData(); } else{ width=-1; diff --git a/src/src/IO/DICOM/DICOMPixelDataHelper.h b/src/src/IO/DICOM/DICOMPixelDataHelper.h index 9adfc6b..93818dd 100644 --- a/src/src/IO/DICOM/DICOMPixelDataHelper.h +++ b/src/src/IO/DICOM/DICOMPixelDataHelper.h @@ -42,6 +42,7 @@ public: */ static void GetRGBPixelData(const char * path, void* data, unsigned long& length); + static int GetOverLayCount(const char *path); static void GetOverlayData(const char * path, void* data, unsigned int& width, unsigned int& height,unsigned int plane = 0); diff --git a/src/src/IO/DICOM/ExtendMedicalImageProperties.h b/src/src/IO/DICOM/ExtendMedicalImageProperties.h index 825b2cf..fc06fec 100644 --- a/src/src/IO/DICOM/ExtendMedicalImageProperties.h +++ b/src/src/IO/DICOM/ExtendMedicalImageProperties.h @@ -54,6 +54,9 @@ public: vtkGetMacro(PixelRepresentation, unsigned short) vtkSetMacro(PixelRepresentation, unsigned short) + vtkGetMacro(HasOverlay, bool) + vtkSetMacro(HasOverlay, bool) + vtkSetVector3Macro(Spacing,double); vtkGetVector3Macro(Spacing,double); @@ -131,6 +134,7 @@ protected: unsigned short SamplePerPixel; unsigned short BitsAllocated; unsigned short PixelRepresentation; + bool HasOverlay = false; std::vector FileNames; std::string uniqueID; vtkNew OrientationMatrix; diff --git a/src/src/IO/DICOM/vtkDICOMImageReader2.cpp b/src/src/IO/DICOM/vtkDICOMImageReader2.cpp index 2b27522..c8565f4 100644 --- a/src/src/IO/DICOM/vtkDICOMImageReader2.cpp +++ b/src/src/IO/DICOM/vtkDICOMImageReader2.cpp @@ -99,6 +99,24 @@ void vtkDICOMImageReader2::ExecuteDataWithInformation(vtkDataObject *output, for (int i = 0; i < properties->GetFileNames().size(); ++i) { const std::string &path = properties->GetFileNames()[i]; + int overlayCount = DICOMPixelDataHelper::GetOverLayCount(path.c_str()); + if (overlayCount > 0){ + if (!OverLayData){ + HasOverlay = true; + OverLayData = vtkImageData::New(); + OverLayData->SetExtent(data->GetExtent()); + OverLayData->SetSpacing(data->GetSpacing()); + OverLayData->SetOrigin(data->GetOrigin()); + OverLayData->AllocateScalars(VTK_UNSIGNED_CHAR,1); + } + unsigned int width = 0; + unsigned int height = 0; + void* overlayBuffer = OverLayData->GetScalarPointer(0, 0, i); + for (int j = 0; j < overlayCount; ++j) { + DICOMPixelDataHelper::GetOverlayData(path.c_str(), overlayBuffer, width, height); + } + + } unsigned long imageDataLength; @@ -115,6 +133,7 @@ void vtkDICOMImageReader2::ExecuteDataWithInformation(vtkDataObject *output, DICOMPixelDataHelper::GetPixelData(path.c_str(), buffer, imageDataLength); } + buffer = ((char *) buffer) + imageDataLength; } @@ -143,3 +162,7 @@ void vtkDICOMImageReader2::SetFileNames(const std::vector& files) { this->DICOMFileNames->push_back(fileString); } } + +vtkImageData *vtkDICOMImageReader2::GetOutputOverLayData() { + return OverLayData; +} diff --git a/src/src/IO/DICOM/vtkDICOMImageReader2.h b/src/src/IO/DICOM/vtkDICOMImageReader2.h index 68849f2..093d5ba 100644 --- a/src/src/IO/DICOM/vtkDICOMImageReader2.h +++ b/src/src/IO/DICOM/vtkDICOMImageReader2.h @@ -34,6 +34,12 @@ public: return DICOMFileNames; } double* GetPixelSpacing(); + + vtkGetMacro(HasOverlay, bool); + vtkSetMacro(HasOverlay, bool); + + vtkImageData* GetOutputOverLayData(); + protected: void SetupOutputInformation(int num_slices); @@ -53,7 +59,9 @@ protected: private: vtkDICOMImageReader2(const vtkDICOMImageReader2&) = delete; void operator=(const vtkDICOMImageReader2&) = delete; - ExtendMedicalImageProperties* properties; + ExtendMedicalImageProperties* properties = nullptr; + vtkImageData* OverLayData = nullptr; + bool HasOverlay = false; };