Data loader 2.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// Created by Krad on 2022/2/8.
|
||||
//
|
||||
|
||||
#include "DICOMDirectoryHelper.h"
|
||||
#include "DICOMHeaderHelper.h"
|
||||
#include "dcmtk/dcmdata/dcfilefo.h"
|
||||
#include "dcmtk/dcmdata/dcdatset.h"
|
||||
#include "ExtendMedicalImageProperties.h"
|
||||
@@ -50,7 +50,7 @@ DICOMTag dicom_tags[] = {
|
||||
{0x0028, 0x1052, "pixel offset"}
|
||||
};
|
||||
|
||||
void DICOMDirectoryHelper::getDirectoryProperties(const char * rootPath, SeriesMap& result){
|
||||
void DICOMHeaderHelper::getDirectoryProperties(const char * rootPath, SeriesMap& result){
|
||||
vtkNew<vtkDirectory> dir;
|
||||
dir->Open(rootPath);
|
||||
vtkIdType fileCount = dir->GetNumberOfFiles();
|
||||
@@ -72,7 +72,7 @@ void DICOMDirectoryHelper::getDirectoryProperties(const char * rootPath, SeriesM
|
||||
}
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::getFileProperty(const std::string &path, SeriesMap& result) {
|
||||
void DICOMHeaderHelper::getFileProperty(const std::string &path, SeriesMap& result) {
|
||||
DcmFileFormat file;
|
||||
// read success!
|
||||
if (file.loadFile(path).good()) {
|
||||
@@ -157,11 +157,11 @@ void DICOMDirectoryHelper::getFileProperty(const std::string &path, SeriesMap& r
|
||||
char buffer[256] = {0};
|
||||
sprintf(buffer, "%ld-%ld", AcquisitionNumber, InstanceNumber);
|
||||
printf("%s\r\n", path.c_str());
|
||||
result[SeriesUID][buffer] = {path, SeriesNumber, AcquisitionNumber, InstanceNumber};
|
||||
result[SeriesUID][buffer] = {path, "",SeriesNumber, AcquisitionNumber, InstanceNumber};
|
||||
}
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::Update() {
|
||||
void DICOMHeaderHelper::Update() {
|
||||
ReadHeader();
|
||||
ArrangeSeriesProperty();
|
||||
// std::unordered_map<std::string, std::unordered_map<std::string,DICOMFileHeader>> series;
|
||||
@@ -200,12 +200,12 @@ void DICOMDirectoryHelper::Update() {
|
||||
SeriesCount = seriesProperties.size();
|
||||
}
|
||||
|
||||
ExtendMedicalImageProperties* DICOMDirectoryHelper::GetSeries(int idx) {
|
||||
ExtendMedicalImageProperties* DICOMHeaderHelper::GetSeries(int idx) {
|
||||
if (seriesProperties.size() <= idx) return nullptr;
|
||||
return seriesProperties[idx];
|
||||
}
|
||||
|
||||
ExtendMedicalImageProperties *DICOMDirectoryHelper::GetSeriesBySeriesUID(const char* seriesUID) {
|
||||
ExtendMedicalImageProperties *DICOMHeaderHelper::GetSeriesBySeriesUID(const char* seriesUID) {
|
||||
for (int i = 0; i < seriesProperties.size(); ++i) {
|
||||
if (0==strcmp(seriesProperties[i]->GetSeriesUID(), seriesUID)){
|
||||
return seriesProperties[i];
|
||||
@@ -214,7 +214,7 @@ ExtendMedicalImageProperties *DICOMDirectoryHelper::GetSeriesBySeriesUID(const c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::Clear() {
|
||||
void DICOMHeaderHelper::Clear() {
|
||||
dirName.clear();
|
||||
fileName.clear();
|
||||
for (auto property : seriesProperties) {
|
||||
@@ -224,7 +224,7 @@ void DICOMDirectoryHelper::Clear() {
|
||||
SeriesCount = 0;
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::readImageProperty(ExtendMedicalImageProperties* property) {
|
||||
void DICOMHeaderHelper::readImageProperty(ExtendMedicalImageProperties* property) {
|
||||
const std::vector<std::string>& files = property->GetFileNames();
|
||||
DcmFileFormat file1;
|
||||
// read success!
|
||||
@@ -314,7 +314,7 @@ void DICOMDirectoryHelper::readImageProperty(ExtendMedicalImageProperties* prope
|
||||
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::readHeaderFromDir(const char * rootPath){
|
||||
void DICOMHeaderHelper::readHeaderFromDir(const char * rootPath){
|
||||
vtkNew<vtkDirectory> dir;
|
||||
dir->Open(rootPath);
|
||||
vtkIdType fileCount = dir->GetNumberOfFiles();
|
||||
@@ -336,12 +336,13 @@ void DICOMDirectoryHelper::readHeaderFromDir(const char * rootPath){
|
||||
}
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::readHeaderFromFile(const char * filePath){
|
||||
void DICOMHeaderHelper::readHeaderFromFile(const char * filePath){
|
||||
DcmFileFormat file;
|
||||
// read success!
|
||||
if (file.loadFile(filePath).good()) {
|
||||
DcmDataset *dataset = file.getDataset();
|
||||
DICOMFileHeader header;
|
||||
header.FilePath = filePath;
|
||||
std::string SeriesUID;
|
||||
dataset->findAndGetOFString(DcmTagKey(0x0020, 0x000e), SeriesUID);
|
||||
|
||||
@@ -359,8 +360,8 @@ void DICOMDirectoryHelper::readHeaderFromFile(const char * filePath){
|
||||
ReadTAGToProperty(PatientName, 0x0010, 0x0010)
|
||||
ReadTAGToProperty(StudyUID, 0x0020, 0x000d)
|
||||
|
||||
dataset->findAndGetSint32(DcmTagKey(0x0028, 0x0010), header.Rows);
|
||||
dataset->findAndGetSint32(DcmTagKey(0x0028, 0x0011), header.Columns);
|
||||
dataset->findAndGetUint16(DcmTagKey(0x0028, 0x0010), header.Rows);
|
||||
dataset->findAndGetUint16(DcmTagKey(0x0028, 0x0011), header.Columns);
|
||||
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1050), header.WindowCenter);
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1051), header.WindowWidth);
|
||||
@@ -386,8 +387,9 @@ void DICOMDirectoryHelper::readHeaderFromFile(const char * filePath){
|
||||
uniqueID.append(StudyUID);
|
||||
uniqueID.append("_");
|
||||
uniqueID.append(SeriesUID);
|
||||
header.SeriesUID = SeriesUID;
|
||||
// series be firstly loaded
|
||||
if (!series.count(SeriesUID)) {
|
||||
if (series.count(uniqueID)==0) {
|
||||
series.emplace(uniqueID,DICOMFileList());
|
||||
}
|
||||
header.calculateImagePosition();
|
||||
@@ -395,7 +397,7 @@ void DICOMDirectoryHelper::readHeaderFromFile(const char * filePath){
|
||||
}
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::ReadHeader() {
|
||||
void DICOMHeaderHelper::ReadHeader() {
|
||||
|
||||
if (!this->dirName.empty()){
|
||||
vtkNew<vtkDirectory> dir;
|
||||
@@ -422,7 +424,7 @@ void DICOMDirectoryHelper::ReadHeader() {
|
||||
}
|
||||
}
|
||||
|
||||
void DICOMDirectoryHelper::ArrangeSeriesProperty() {
|
||||
void DICOMHeaderHelper::ArrangeSeriesProperty() {
|
||||
for (auto item : series) {
|
||||
//sort by series, instance, AcquisitionNumber
|
||||
std::sort(item.second.begin(), item.second.end(), [](auto v1, auto v2) {
|
||||
@@ -445,21 +447,22 @@ void DICOMDirectoryHelper::ArrangeSeriesProperty() {
|
||||
[](auto v1,auto v2){
|
||||
return v1.image_position<v2.image_position;
|
||||
});
|
||||
seriesProperties.push_back(createProperty(item.second, splitIndex[j], beginOffset));
|
||||
auto p = createProperty(item.second, splitIndex[j], beginOffset);
|
||||
if (p)seriesProperties.push_back(p);
|
||||
beginOffset = splitIndex[j];
|
||||
}
|
||||
//sort the last image set
|
||||
if (splitIndex.size()>0) {
|
||||
std::sort(item.second.begin() + beginOffset, item.second.end(),
|
||||
[](auto v1, auto v2) {
|
||||
return v1.image_position < v2.image_position;
|
||||
});
|
||||
seriesProperties.push_back(createProperty(item.second, item.second.size()-1, beginOffset));
|
||||
}
|
||||
auto p = createProperty(item.second, item.second.size(), beginOffset);
|
||||
if (p)seriesProperties.push_back(p);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ExtendMedicalImageProperties* DICOMDirectoryHelper::createProperty(const std::vector<DICOMFileHeader>& headerList, int splitIndex, int beginOffset) {
|
||||
ExtendMedicalImageProperties* DICOMHeaderHelper::createProperty(const std::vector<DICOMFileHeader>& headerList, int splitIndex, int beginOffset) {
|
||||
auto property = ExtendMedicalImageProperties::New();
|
||||
std::vector<std::string> files;
|
||||
for (int i = beginOffset; i < splitIndex; ++i) {
|
||||
@@ -506,20 +509,28 @@ ExtendMedicalImageProperties* DICOMDirectoryHelper::createProperty(const std::ve
|
||||
double thickness= 1.0;
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0008, 0x0050), thickness);
|
||||
double RescaleSlope= 1.0;
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1052), RescaleSlope);
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1053), RescaleSlope);
|
||||
double RescaleOffset= 1.0;
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1053), RescaleOffset);
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1052), RescaleOffset);
|
||||
unsigned short bitsAllocated= 1;
|
||||
dataset->findAndGetUint16(DcmTagKey(0x0028, 0x1000), bitsAllocated);
|
||||
dataset->findAndGetUint16(DcmTagKey(0x0028, 0x0100), bitsAllocated);
|
||||
unsigned short PixelRepresentation= 0;
|
||||
dataset->findAndGetUint16(DcmTagKey(0x0028, 0x1000), PixelRepresentation);
|
||||
dataset->findAndGetUint16(DcmTagKey(0x0028, 0x0103), PixelRepresentation);
|
||||
property->SetSeriesUID(header.SeriesUID.c_str());
|
||||
property->SetRows(header.Rows);
|
||||
property->SetColumns(header.Columns);
|
||||
property->SetSpacing(header.Spacing[0],header.Spacing[1],thickness);
|
||||
property->SetRescaleSlope(RescaleSlope);
|
||||
property->SetRescaleOffset(RescaleOffset);
|
||||
property->SetBitsAllocated(bitsAllocated);
|
||||
property->SetPixelRepresentation(PixelRepresentation);
|
||||
}
|
||||
if (headerList.size()>1){
|
||||
else{
|
||||
printf( " file:%s load error!\r\b", header.FilePath.c_str() );
|
||||
property->Delete();
|
||||
return nullptr;
|
||||
}
|
||||
if (splitIndex-beginOffset>1){
|
||||
const DICOMFileHeader& header2 = headerList[beginOffset+1];
|
||||
double spacing2 = sqrt(vtkMath::Distance2BetweenPoints(header.Position,header2.Position));
|
||||
property->SetSpacing(property->GetSpacing()[0],property->GetSpacing()[1],spacing2);
|
||||
@@ -14,12 +14,13 @@ class ExtendMedicalImageProperties;
|
||||
|
||||
struct DICOMFileHeader {
|
||||
std::string FilePath;
|
||||
std::string SeriesUID;
|
||||
long SeriesNumber = 0;
|
||||
long AcquisitionNumber = 0;
|
||||
long InstanceNumber = 0;
|
||||
double Spacing[2] = {1., 1.};
|
||||
long Rows;
|
||||
long Columns;
|
||||
unsigned short Rows;
|
||||
unsigned short Columns;
|
||||
unsigned short SamplePerPixel;
|
||||
double WindowCenter = 0;
|
||||
double WindowWidth = 0;
|
||||
@@ -52,11 +53,11 @@ typedef std::vector<DICOMFileHeader> DICOMFileList;
|
||||
typedef std::unordered_map<std::string, DICOMFileMap> SeriesMap;
|
||||
typedef std::unordered_map<std::string, DICOMFileList> SeriesFileMap;
|
||||
|
||||
class DICOMDirectoryHelper {
|
||||
class DICOMHeaderHelper {
|
||||
public:
|
||||
DICOMDirectoryHelper() = default;
|
||||
DICOMHeaderHelper() = default;
|
||||
|
||||
~DICOMDirectoryHelper() {
|
||||
~DICOMHeaderHelper() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
166
src/src/IO/DICOM/DICOMPixelDataHelper.cpp
Normal file
166
src/src/IO/DICOM/DICOMPixelDataHelper.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/9.
|
||||
//
|
||||
|
||||
#include "DICOMPixelDataHelper.h"
|
||||
#include <dcmtk/dcmdata/dcrledrg.h>
|
||||
#include <dcmtk/dcmjpeg/djdecode.h>
|
||||
#include <dcmtk/dcmjpls/djdecode.h>
|
||||
#include <dcmtk/dcmdata/dcfilefo.h>
|
||||
#include <dcmtk/dcmimgle/dcmimage.h>
|
||||
#include <dcmtk/dcmimgle/dipixel.h>
|
||||
#include "ExtendMedicalImageProperties.h"
|
||||
#ifdef OPENJPEG
|
||||
#include "openjpeg-2.3/openjpeg.h"
|
||||
#endif
|
||||
|
||||
void DICOMPixelDataHelper::InitCodecs() {
|
||||
DcmRLEDecoderRegistration::registerCodecs(OFFalse, OFTrue);//注册解码器
|
||||
/// register JPEG decompression codecs
|
||||
DJDecoderRegistration::registerCodecs();//注册解码器
|
||||
DJLSDecoderRegistration::registerCodecs();
|
||||
#ifdef OPENJPEG
|
||||
FMJPEG2KDecoderRegistration::registerCodecs();//jpeg2000
|
||||
#endif
|
||||
}
|
||||
|
||||
void DICOMPixelDataHelper::FinalizeCodecs() {
|
||||
DcmRLEDecoderRegistration::cleanup();
|
||||
DJDecoderRegistration::cleanup();
|
||||
DJLSDecoderRegistration::cleanup();
|
||||
#ifdef OPENJPEG
|
||||
FMJPEG2KDecoderRegistration::cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DICOMPixelDataHelper::GetThumbnailData(ExtendMedicalImageProperties *property, unsigned char* data,
|
||||
unsigned long& length) {
|
||||
double *wlww = property->GetNthWindowLevelPreset(0);
|
||||
int ww = wlww ? ((int) wlww[0]) : (512);
|
||||
int wl = wlww ? ((int) wlww[1]) : (256);
|
||||
int sample = property->GetSamplePerPixel();
|
||||
DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法
|
||||
if (fileFormat->loadFile(property->GetThumbnailFileName()).good()) {
|
||||
DcmDataset *dset = fileFormat->getDataset();
|
||||
DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
|
||||
DicomImage *sdcmImage = dcmImage.createScaledImage(100.0, 0.0, 0, 1);
|
||||
sdcmImage->setWindow(wl, ww);
|
||||
sdcmImage->showAllOverlays();
|
||||
length = sdcmImage->getOutputDataSize(8);
|
||||
unsigned char *outputData = (unsigned char *) sdcmImage->getOutputData(8);//按8位的位宽取数据
|
||||
data = new unsigned char[length];
|
||||
memcpy(data, outputData, length);
|
||||
delete sdcmImage;
|
||||
}
|
||||
delete fileFormat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DICOMPixelDataHelper::GetPixelData(const char * path, void *data, unsigned long& length) {
|
||||
DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法
|
||||
if (fileFormat->loadFile(path).good()) {
|
||||
DcmDataset *dset = fileFormat->getDataset();
|
||||
DicomImage* dcmImage = new DicomImage(fileFormat, dset->getOriginalXfer(),CIF_MayDetachPixelData);
|
||||
const DiPixel* pixelData = dcmImage->getInterData();//rescaled
|
||||
unsigned long dataBits = 1;
|
||||
switch (pixelData->getRepresentation()){
|
||||
case EPR_Uint8:
|
||||
case EPR_Sint8:
|
||||
break;
|
||||
case EPR_Uint16:
|
||||
case EPR_Sint16:
|
||||
dataBits = 2;
|
||||
break;
|
||||
case EPR_Uint32:
|
||||
case EPR_Sint32:
|
||||
dataBits = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
const void * dd = pixelData->getData();
|
||||
length = pixelData->getCount() ;
|
||||
length = length*dataBits;
|
||||
memcpy(data,dd, length);
|
||||
delete dcmImage;
|
||||
} else{
|
||||
length=-1;
|
||||
}
|
||||
delete fileFormat;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void convertAndRescale(const void* input, void* output, double slope, double intercept, unsigned long length)
|
||||
{
|
||||
const T* in = static_cast<const T*>(input);
|
||||
float* out = static_cast<float*>(output);
|
||||
for (int i = 0; i <length ; ++i) {
|
||||
*(out++) = static_cast<float>(static_cast<double>(*(in++))*slope+intercept);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* DICOMPixelDataHelper::GetPixelDataFloat(const char *path, unsigned long &length) {
|
||||
void* data = nullptr;
|
||||
DcmFileFormat *fileFormat = new DcmFileFormat();
|
||||
if (fileFormat->loadFile(path).good()) {
|
||||
DcmDataset *dataset = fileFormat->getDataset();
|
||||
DicomImage dcmImage(fileFormat, dataset->getOriginalXfer(), CIF_IgnoreModalityTransformation);
|
||||
const DiPixel* pixelData = dcmImage.getInterData();//no rescaled
|
||||
length = pixelData->getCount();
|
||||
const void* pData = pixelData->getData();
|
||||
data = new float [length];
|
||||
double slope= 1.0;
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1053), slope);
|
||||
double intercept= 0.0;
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1052), intercept);
|
||||
switch (pixelData->getRepresentation()){
|
||||
case EPR_Uint8:
|
||||
convertAndRescale<Uint8>(pData,data,slope,intercept,length);
|
||||
break;
|
||||
case EPR_Sint8:
|
||||
convertAndRescale<Sint8>(pData,data,slope,intercept,length);
|
||||
break;
|
||||
case EPR_Uint16:
|
||||
convertAndRescale<Uint16>(pData,data,slope,intercept,length);
|
||||
break;
|
||||
case EPR_Sint16:
|
||||
convertAndRescale<Sint16>(pData,data,slope,intercept,length);
|
||||
break;
|
||||
case EPR_Uint32:
|
||||
convertAndRescale<Uint32>(pData,data,slope,intercept,length);
|
||||
break;
|
||||
case EPR_Sint32:
|
||||
convertAndRescale<Sint32>(pData,data,slope,intercept,length);
|
||||
break;
|
||||
}
|
||||
} else{
|
||||
length=-1;
|
||||
}
|
||||
delete fileFormat;
|
||||
return data;
|
||||
}
|
||||
|
||||
void DICOMPixelDataHelper::GetOverlayData(const char *path, void *data,
|
||||
unsigned int& width, unsigned int& height, unsigned int plane) {
|
||||
DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法
|
||||
if (fileFormat->loadFile(path).good()) {
|
||||
DcmDataset *dset = fileFormat->getDataset();
|
||||
DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
|
||||
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);
|
||||
}
|
||||
else{
|
||||
width=-1;
|
||||
height=-1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
width=-1;
|
||||
height=-1;
|
||||
}
|
||||
delete fileFormat;
|
||||
}
|
||||
29
src/src/IO/DICOM/DICOMPixelDataHelper.h
Normal file
29
src/src/IO/DICOM/DICOMPixelDataHelper.h
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/9.
|
||||
//
|
||||
|
||||
#ifndef OMEGAV_DICOMPIXELDATAHELPER_H
|
||||
#define OMEGAV_DICOMPIXELDATAHELPER_H
|
||||
|
||||
class ExtendMedicalImageProperties;
|
||||
|
||||
class DICOMPixelDataHelper {
|
||||
public:
|
||||
DICOMPixelDataHelper() = default;
|
||||
|
||||
~DICOMPixelDataHelper() {
|
||||
}
|
||||
static void GetThumbnailData(ExtendMedicalImageProperties *property, unsigned char* data,
|
||||
unsigned long& length);
|
||||
static void GetPixelData(const char * path, void* data,unsigned long& length);
|
||||
static void* GetPixelDataFloat(const char * path,unsigned long& length);
|
||||
static void GetOverlayData(const char * path, void* data,
|
||||
unsigned int& width, unsigned int& height,unsigned int plane = 0);
|
||||
|
||||
static void InitCodecs();
|
||||
|
||||
static void FinalizeCodecs();
|
||||
};
|
||||
|
||||
|
||||
#endif //OMEGAV_DICOMPIXELDATAHELPER_H
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "DicomLoader.h"
|
||||
|
||||
#include "Common/SeriesImageSet.h"
|
||||
#include "DICOMDirectoryHelper.h"
|
||||
#include "DICOMHeaderHelper.h"
|
||||
#include "ExtendMedicalImageProperties.h"
|
||||
#include "vtkDICOMImageReader2.h"
|
||||
#include "vtkImageData.h"
|
||||
@@ -131,7 +131,8 @@ SeriesImageSet* DicomLoader::getSeriesImageSet(const std::string& uniqueID)//, D
|
||||
});
|
||||
if (iter==imageProperties.end()) return nullptr;
|
||||
|
||||
reader->SetFileNames((*iter)->GetFileNames());
|
||||
// reader->SetFileNames((*iter)->GetFileNames());
|
||||
reader->SetImageProperties((*iter));
|
||||
reader->Update();
|
||||
auto imageData = reader->GetOutput();
|
||||
SeriesImageSet* result = new SeriesImageSet((*iter),imageData);
|
||||
@@ -145,7 +146,7 @@ SeriesImageSet* DicomLoader::getSeriesImageSet(const std::string& uniqueID)//, D
|
||||
|
||||
void DicomLoader::readTags(const std::string &dir, SeriesOpenMode openMode)
|
||||
{
|
||||
DICOMDirectoryHelper DICOMHelper;
|
||||
DICOMHeaderHelper DICOMHelper;
|
||||
if (openMode == FILE_OPEN_MODE)
|
||||
{
|
||||
//m_itkSeriesReader->SetFileName(m_dicomName.toStdString());
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
class SeriesImageSet;
|
||||
|
||||
|
||||
class DICOMDirectoryHelper;
|
||||
class DICOMHeaderHelper;
|
||||
class ExtendMedicalImageProperties;
|
||||
class vtkDICOMImageReader2;
|
||||
typedef std::map<std::string, SeriesImageSet*> ImageSetStore;
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
|
||||
const char* GetThumbnailFileName(){
|
||||
if (FileNames.empty()) return nullptr;
|
||||
return FileNames[FileNames.size()/2].data();
|
||||
return FileNames[0].data();
|
||||
}
|
||||
unsigned long long GetSliceCount(){
|
||||
return FileNames.size();
|
||||
|
||||
@@ -9,13 +9,10 @@
|
||||
#include "vtkObjectFactory.h"
|
||||
#include "vtkPointData.h"
|
||||
|
||||
#include "DICOMAppHelper.h"
|
||||
#include "DICOMParser.h"
|
||||
#include "IO/DICOM/DICOMPixelDataHelper.h"
|
||||
|
||||
vtkStandardNewMacro(vtkDICOMImageReader2);
|
||||
|
||||
|
||||
|
||||
|
||||
vtkDICOMImageReader2::vtkDICOMImageReader2():vtkDICOMImageReader() {
|
||||
|
||||
}
|
||||
@@ -80,124 +77,51 @@ void vtkDICOMImageReader2::ExecuteInformation() {
|
||||
}
|
||||
|
||||
void vtkDICOMImageReader2::ExecuteDataWithInformation(vtkDataObject *output,
|
||||
vtkInformation *outInfo)
|
||||
{
|
||||
vtkInformation *outInfo) {
|
||||
vtkImageData *data = this->AllocateOutputData(output, outInfo);
|
||||
|
||||
if (!properties)
|
||||
{
|
||||
vtkErrorMacro( << "No image properties set for the reader.");
|
||||
this->SetErrorCode( vtkErrorCode::FileNotFoundError );
|
||||
if (!properties) {
|
||||
vtkErrorMacro(<< "No image properties set for the reader.");
|
||||
this->SetErrorCode(vtkErrorCode::FileNotFoundError);
|
||||
return;
|
||||
}
|
||||
|
||||
data->GetPointData()->GetScalars()->SetName("DICOMImage");
|
||||
|
||||
this->ComputeDataIncrements();
|
||||
|
||||
if (this->FileName)
|
||||
void *buffer = data->GetScalarPointer();
|
||||
if (buffer == nullptr) {
|
||||
vtkErrorMacro(<< "No memory allocated for image data!");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < properties->GetFileNames().size(); ++i) {
|
||||
const std::string& path = properties->GetFileNames()[i];
|
||||
if (this->DataScalarType == VTK_FLOAT)
|
||||
{
|
||||
vtkDebugMacro( << "Single file : " << this->FileName);
|
||||
this->Parser->ClearAllDICOMTagCallbacks();
|
||||
this->Parser->OpenFile(this->FileName);
|
||||
this->AppHelper->Clear();
|
||||
this->AppHelper->RegisterCallbacks(this->Parser);
|
||||
this->AppHelper->RegisterPixelDataCallback(this->Parser);
|
||||
void *imgData = nullptr;
|
||||
|
||||
this->Parser->ReadHeader();
|
||||
|
||||
void* imgData = nullptr;
|
||||
DICOMParser::VRTypes dataType;
|
||||
unsigned long imageDataLength;
|
||||
|
||||
this->AppHelper->GetImageData(imgData, dataType, imageDataLength);
|
||||
if( !imageDataLength )
|
||||
{
|
||||
vtkErrorMacro( << "There was a problem retrieving data from: " << this->FileName );
|
||||
this->SetErrorCode( vtkErrorCode::FileFormatError );
|
||||
imgData = DICOMPixelDataHelper::GetPixelDataFloat(path.c_str(),imageDataLength);
|
||||
if(imgData){
|
||||
//calc size of float
|
||||
imageDataLength = imageDataLength * sizeof(float);
|
||||
unsigned char *b = (unsigned char *) buffer;
|
||||
unsigned char *iData = (unsigned char *) imgData;
|
||||
memcpy(b, imgData, imageDataLength);
|
||||
buffer = ((char*) buffer) + imageDataLength;
|
||||
}
|
||||
else{
|
||||
vtkErrorMacro(<< "Can't read data from path:"<<path.c_str()<<"!");
|
||||
return;
|
||||
}
|
||||
|
||||
void* buffer = data->GetScalarPointer();
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
vtkErrorMacro(<< "No memory allocated for image data!");
|
||||
return;
|
||||
}
|
||||
// DICOM stores the upper left pixel as the first pixel in an
|
||||
// image. VTK stores the lower left pixel as the first pixel in
|
||||
// an image. Need to flip the data.
|
||||
vtkIdType rowLength;
|
||||
rowLength = this->DataIncrements[1];
|
||||
unsigned char *b = (unsigned char *)buffer;
|
||||
unsigned char *iData = (unsigned char *)imgData;
|
||||
memcpy(b,imgData,imageDataLength);
|
||||
// iData += (imageDataLength - rowLength); // beginning of last row
|
||||
// for (int i=0; i < this->AppHelper->GetHeight(); ++i)
|
||||
// {
|
||||
// memcpy(b, iData, rowLength);
|
||||
// b += rowLength;
|
||||
// iData -= rowLength;
|
||||
// }
|
||||
}
|
||||
else if (!this->DICOMFileNames->empty())
|
||||
{
|
||||
vtkDebugMacro( << "Multiple files (" << static_cast<int>(this->DICOMFileNames->size()) << ")");
|
||||
this->Parser->ClearAllDICOMTagCallbacks();
|
||||
this->AppHelper->Clear();
|
||||
this->AppHelper->RegisterCallbacks(this->Parser);
|
||||
this->AppHelper->RegisterPixelDataCallback(this->Parser);
|
||||
else{
|
||||
void *imgData = nullptr;
|
||||
|
||||
void* buffer = data->GetScalarPointer();
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
vtkErrorMacro(<< "No memory allocated for image data!");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string>::iterator fiter;
|
||||
|
||||
int count = 0;
|
||||
vtkIdType numFiles = static_cast<int>(this->DICOMFileNames->size());
|
||||
|
||||
for (fiter = this->DICOMFileNames->begin();
|
||||
fiter != this->DICOMFileNames->end();
|
||||
++fiter)
|
||||
{
|
||||
count++;
|
||||
const char *file = fiter->c_str();
|
||||
vtkDebugMacro( << "File : " << file );
|
||||
this->Parser->OpenFile( file );
|
||||
this->Parser->ReadHeader();
|
||||
|
||||
void* imgData = nullptr;
|
||||
DICOMParser::VRTypes dataType;
|
||||
unsigned long imageDataLengthInBytes;
|
||||
|
||||
this->AppHelper->GetImageData(imgData, dataType, imageDataLengthInBytes);
|
||||
if( !imageDataLengthInBytes )
|
||||
{
|
||||
vtkErrorMacro( << "There was a problem retrieving data from: " << file );
|
||||
this->SetErrorCode( vtkErrorCode::FileFormatError );
|
||||
return;
|
||||
}
|
||||
|
||||
// DICOM stores the upper left pixel as the first pixel in an
|
||||
// image. VTK stores the lower left pixel as the first pixel in
|
||||
// an image. Need to flip the data.
|
||||
vtkIdType rowLength;
|
||||
rowLength = this->DataIncrements[1];
|
||||
unsigned char *b = (unsigned char *)buffer;
|
||||
unsigned char *iData = (unsigned char *)imgData;
|
||||
memcpy(b,imgData,imageDataLengthInBytes);
|
||||
buffer = ((char*) buffer) + imageDataLengthInBytes;
|
||||
|
||||
this->UpdateProgress(float(count)/float(numFiles));
|
||||
int len = static_cast<int> (strlen((const char*) (*fiter).c_str()));
|
||||
char* filename = new char[len+1];
|
||||
strcpy(filename, (const char*) (*fiter).c_str());
|
||||
this->SetProgressText(filename);
|
||||
delete[] filename;
|
||||
unsigned long imageDataLength;
|
||||
unsigned char *b = (unsigned char *) buffer;
|
||||
DICOMPixelDataHelper::GetPixelData(path.c_str(), buffer,imageDataLength);
|
||||
buffer = ((char*) buffer) + imageDataLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,10 +134,6 @@ double* vtkDICOMImageReader2::GetPixelSpacing()
|
||||
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 ||
|
||||
@@ -223,18 +143,7 @@ void vtkDICOMImageReader2::SetFileNames(const std::vector<std::string>& files) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user