Fix pixel data read logic.

This commit is contained in:
Krad
2022-09-14 14:03:24 +08:00
parent 2b919ec011
commit a92a3c2016
4 changed files with 90 additions and 57 deletions

View File

@@ -61,10 +61,10 @@ void DICOMPixelDataHelper::GetPixelData(const char * path, void *data, unsigned
DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法 DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法
if (fileFormat->loadFile(path).good()) { if (fileFormat->loadFile(path).good()) {
DcmDataset *dset = fileFormat->getDataset(); DcmDataset *dset = fileFormat->getDataset();
DicomImage* dcmImage = new DicomImage(fileFormat, dset->getOriginalXfer(),CIF_MayDetachPixelData); DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
const DiPixel* pixelData = dcmImage->getInterData();//rescaled const DiPixel *pixelData = dcmImage.getInterData();//rescaled
unsigned long dataBits = 1; unsigned long dataBits = 1;
switch (pixelData->getRepresentation()){ switch (pixelData->getRepresentation()) {
case EPR_Uint8: case EPR_Uint8:
case EPR_Sint8: case EPR_Sint8:
break; break;
@@ -77,12 +77,10 @@ void DICOMPixelDataHelper::GetPixelData(const char * path, void *data, unsigned
dataBits = 4; dataBits = 4;
break; break;
} }
const void *dd = pixelData->getData();
const void * dd = pixelData->getData(); length = pixelData->getCount();
length = pixelData->getCount() ; length = length * dataBits;
length = length*dataBits; memcpy(data, dd, length);
memcpy(data,dd, length);
delete dcmImage;
} else{ } else{
length=-1; length=-1;
} }
@@ -100,8 +98,8 @@ void convertAndRescale(const void* input, void* output, double slope, double int
} }
void* DICOMPixelDataHelper::GetPixelDataFloat(const char *path, unsigned long &length) { void DICOMPixelDataHelper::GetPixelDataFloat(const char *path, void *data, unsigned long &length) {
void* data = nullptr; void* temp = nullptr;
DcmFileFormat *fileFormat = new DcmFileFormat(); DcmFileFormat *fileFormat = new DcmFileFormat();
if (fileFormat->loadFile(path).good()) { if (fileFormat->loadFile(path).good()) {
DcmDataset *dataset = fileFormat->getDataset(); DcmDataset *dataset = fileFormat->getDataset();
@@ -109,36 +107,51 @@ void* DICOMPixelDataHelper::GetPixelDataFloat(const char *path, unsigned long &l
const DiPixel* pixelData = dcmImage.getInterData();//no rescaled const DiPixel* pixelData = dcmImage.getInterData();//no rescaled
length = pixelData->getCount(); length = pixelData->getCount();
const void* pData = pixelData->getData(); const void* pData = pixelData->getData();
data = new float [length]; double slope = 1.0;
double slope= 1.0;
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1053), slope); dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1053), slope);
double intercept= 0.0; double intercept = 0.0;
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1052), intercept); dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1052), intercept);
switch (pixelData->getRepresentation()){ switch (pixelData->getRepresentation()){
case EPR_Uint8: case EPR_Uint8:
convertAndRescale<Uint8>(pData,data,slope,intercept,length); convertAndRescale<Uint8>(pData, data, slope, intercept, length);
break; break;
case EPR_Sint8: case EPR_Sint8:
convertAndRescale<Sint8>(pData,data,slope,intercept,length); convertAndRescale<Sint8>(pData, data, slope, intercept, length);
break; break;
case EPR_Uint16: case EPR_Uint16:
convertAndRescale<Uint16>(pData,data,slope,intercept,length); convertAndRescale<Uint16>(pData, data, slope, intercept, length);
break; break;
case EPR_Sint16: case EPR_Sint16:
convertAndRescale<Sint16>(pData,data,slope,intercept,length); convertAndRescale<Sint16>(pData, data, slope, intercept, length);
break; break;
case EPR_Uint32: case EPR_Uint32:
convertAndRescale<Uint32>(pData,data,slope,intercept,length); convertAndRescale<Uint32>(pData, data, slope, intercept, length);
break; break;
case EPR_Sint32: case EPR_Sint32:
convertAndRescale<Sint32>(pData,data,slope,intercept,length); convertAndRescale<Sint32>(pData, data, slope, intercept, length);
break; break;
} }
length = length * sizeof(float);
} else{
length=-1;
}
delete fileFormat;
}
void DICOMPixelDataHelper::GetRGBPixelData(const char *path, void *data, unsigned long &length) {
DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法
if (fileFormat->loadFile(path).good()) {
DcmDataset *dset = fileFormat->getDataset();
DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
dcmImage.hideAllOverlays();
length = dcmImage.getOutputDataSize(8);
const void *dd = dcmImage.getOutputData(8);
memcpy(data, dd, length);
dcmImage.deleteOutputData();
} else{ } else{
length=-1; length=-1;
} }
delete fileFormat; delete fileFormat;
return data;
} }
void DICOMPixelDataHelper::GetOverlayData(const char *path, void *data, void DICOMPixelDataHelper::GetOverlayData(const char *path, void *data,

View File

@@ -7,6 +7,9 @@
class ExtendMedicalImageProperties; class ExtendMedicalImageProperties;
/**
* DICOM file Pixel Data read helper
*/
class DICOMPixelDataHelper { class DICOMPixelDataHelper {
public: public:
DICOMPixelDataHelper() = default; DICOMPixelDataHelper() = default;
@@ -15,13 +18,42 @@ public:
} }
static void GetThumbnailData(ExtendMedicalImageProperties *property, unsigned char* data, static void GetThumbnailData(ExtendMedicalImageProperties *property, unsigned char* data,
unsigned long& length); unsigned long& length);
static void GetPixelData(const char * path, void* data,unsigned long& length); /**
static void* GetPixelDataFloat(const char * path,unsigned long& length); * Get Pixel Data with Rescaled, result is calculate as integer, and arrange as integer.
* @param path dcm file absolute path
* @param data output data buffer pointer
* @param length output data length
*/
static void GetPixelData(const char * path, void* data, unsigned long& length);
/**
* Get Pixel Data with Rescaled, result is calculate as Float, and arrange as Float.
* @param path dcm file absolute path
* @param data output data buffer pointer
* @param length output data length
*/
static void GetPixelDataFloat(const char * path, void* data, unsigned long& length);
/**
* Get colorful Pixel Data as three component R,G,B color value.
* @param path dcm file absolute path
* @param data output data buffer pointer
* @param length output data length
*/
static void GetRGBPixelData(const char * path, void* data, unsigned long& length);
static void GetOverlayData(const char * path, void* data, static void GetOverlayData(const char * path, void* data,
unsigned int& width, unsigned int& height,unsigned int plane = 0); unsigned int& width, unsigned int& height,unsigned int plane = 0);
/**
* Init decompress Codecs, must be called before other method.
*/
static void InitCodecs(); static void InitCodecs();
/**
* Finalize decompress Codecs, must be called after other method have done.
*/
static void FinalizeCodecs(); static void FinalizeCodecs();
}; };

View File

@@ -98,11 +98,3 @@ void ExtendMedicalImageProperties::GenerateUniqueID() {
this->SetUniqueID(uniqueID.c_str()); this->SetUniqueID(uniqueID.c_str());
} }
bool ExtendMedicalImageProperties::RescaledImageDataIsUnsignedChar() {
bool charData = BitsAllocated == 8;
bool noScale = ((int)(this->RescaleOffset) == 0) && ((int)(this->RescaleSlope) == 1);
bool unSign = (this->PixelRepresentation == 0);
bool color = SamplePerPixel == 3;
return (color || (charData && unSign && noScale));
}

View File

@@ -93,37 +93,33 @@ void vtkDICOMImageReader2::ExecuteDataWithInformation(vtkDataObject *output,
vtkErrorMacro(<< "No memory allocated for image data!"); vtkErrorMacro(<< "No memory allocated for image data!");
return; return;
} }
// init codes to support compressed file
DICOMPixelDataHelper::InitCodecs();
for (int i = 0; i < properties->GetFileNames().size(); ++i) { for (int i = 0; i < properties->GetFileNames().size(); ++i) {
const std::string& path = properties->GetFileNames()[i]; const std::string &path = properties->GetFileNames()[i];
if (this->DataScalarType == VTK_FLOAT)
{
void *imgData = nullptr;
unsigned long imageDataLength; unsigned long imageDataLength;
if (this->DataScalarType == VTK_FLOAT) {
DICOMPixelDataHelper::GetPixelDataFloat(path.c_str(), buffer, imageDataLength);
} else if (NumberOfScalarComponents > 1) {
DICOMPixelDataHelper::GetRGBPixelData(path.c_str(), buffer, imageDataLength);
} else {
DICOMPixelDataHelper::GetPixelData(path.c_str(), buffer, imageDataLength);
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;
}
}
else{
void *imgData = nullptr;
unsigned long imageDataLength;
unsigned char *b = (unsigned char *) buffer;
DICOMPixelDataHelper::GetPixelData(path.c_str(), buffer,imageDataLength);
buffer = ((char*) buffer) + imageDataLength;
} }
buffer = ((char *) buffer) + imageDataLength;
} }
// finalize codecs
DICOMPixelDataHelper::FinalizeCodecs();
} }
double* vtkDICOMImageReader2::GetPixelSpacing() double* vtkDICOMImageReader2::GetPixelSpacing()