Fix pixel data read logic.
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user