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();//读取文件获取传输语法
|
||||
if (fileFormat->loadFile(path).good()) {
|
||||
DcmDataset *dset = fileFormat->getDataset();
|
||||
DicomImage* dcmImage = new DicomImage(fileFormat, dset->getOriginalXfer(),CIF_MayDetachPixelData);
|
||||
const DiPixel* pixelData = dcmImage->getInterData();//rescaled
|
||||
DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
|
||||
const DiPixel *pixelData = dcmImage.getInterData();//rescaled
|
||||
unsigned long dataBits = 1;
|
||||
switch (pixelData->getRepresentation()){
|
||||
switch (pixelData->getRepresentation()) {
|
||||
case EPR_Uint8:
|
||||
case EPR_Sint8:
|
||||
break;
|
||||
@@ -77,12 +77,10 @@ void DICOMPixelDataHelper::GetPixelData(const char * path, void *data, unsigned
|
||||
dataBits = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
const void * dd = pixelData->getData();
|
||||
length = pixelData->getCount() ;
|
||||
length = length*dataBits;
|
||||
memcpy(data,dd, length);
|
||||
delete dcmImage;
|
||||
const void *dd = pixelData->getData();
|
||||
length = pixelData->getCount();
|
||||
length = length * dataBits;
|
||||
memcpy(data, dd, length);
|
||||
} else{
|
||||
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* data = nullptr;
|
||||
void DICOMPixelDataHelper::GetPixelDataFloat(const char *path, void *data, unsigned long &length) {
|
||||
void* temp = nullptr;
|
||||
DcmFileFormat *fileFormat = new DcmFileFormat();
|
||||
if (fileFormat->loadFile(path).good()) {
|
||||
DcmDataset *dataset = fileFormat->getDataset();
|
||||
@@ -109,36 +107,51 @@ void* DICOMPixelDataHelper::GetPixelDataFloat(const char *path, unsigned long &l
|
||||
const DiPixel* pixelData = dcmImage.getInterData();//no rescaled
|
||||
length = pixelData->getCount();
|
||||
const void* pData = pixelData->getData();
|
||||
data = new float [length];
|
||||
double slope= 1.0;
|
||||
double slope = 1.0;
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1053), slope);
|
||||
double intercept= 0.0;
|
||||
double intercept = 0.0;
|
||||
dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1052), intercept);
|
||||
switch (pixelData->getRepresentation()){
|
||||
case EPR_Uint8:
|
||||
convertAndRescale<Uint8>(pData,data,slope,intercept,length);
|
||||
convertAndRescale<Uint8>(pData, data, slope, intercept, length);
|
||||
break;
|
||||
case EPR_Sint8:
|
||||
convertAndRescale<Sint8>(pData,data,slope,intercept,length);
|
||||
convertAndRescale<Sint8>(pData, data, slope, intercept, length);
|
||||
break;
|
||||
case EPR_Uint16:
|
||||
convertAndRescale<Uint16>(pData,data,slope,intercept,length);
|
||||
convertAndRescale<Uint16>(pData, data, slope, intercept, length);
|
||||
break;
|
||||
case EPR_Sint16:
|
||||
convertAndRescale<Sint16>(pData,data,slope,intercept,length);
|
||||
convertAndRescale<Sint16>(pData, data, slope, intercept, length);
|
||||
break;
|
||||
case EPR_Uint32:
|
||||
convertAndRescale<Uint32>(pData,data,slope,intercept,length);
|
||||
convertAndRescale<Uint32>(pData, data, slope, intercept, length);
|
||||
break;
|
||||
case EPR_Sint32:
|
||||
convertAndRescale<Sint32>(pData,data,slope,intercept,length);
|
||||
convertAndRescale<Sint32>(pData, data, slope, intercept, length);
|
||||
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{
|
||||
length=-1;
|
||||
}
|
||||
delete fileFormat;
|
||||
return data;
|
||||
}
|
||||
|
||||
void DICOMPixelDataHelper::GetOverlayData(const char *path, void *data,
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
class ExtendMedicalImageProperties;
|
||||
|
||||
/**
|
||||
* DICOM file Pixel Data read helper
|
||||
*/
|
||||
class DICOMPixelDataHelper {
|
||||
public:
|
||||
DICOMPixelDataHelper() = default;
|
||||
@@ -15,13 +18,42 @@ public:
|
||||
}
|
||||
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);
|
||||
/**
|
||||
* 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,
|
||||
unsigned int& width, unsigned int& height,unsigned int plane = 0);
|
||||
|
||||
/**
|
||||
* Init decompress Codecs, must be called before other method.
|
||||
*/
|
||||
static void InitCodecs();
|
||||
|
||||
/**
|
||||
* Finalize decompress Codecs, must be called after other method have done.
|
||||
*/
|
||||
static void FinalizeCodecs();
|
||||
};
|
||||
|
||||
|
||||
@@ -98,11 +98,3 @@ void ExtendMedicalImageProperties::GenerateUniqueID() {
|
||||
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!");
|
||||
return;
|
||||
}
|
||||
|
||||
// init codes to support compressed file
|
||||
DICOMPixelDataHelper::InitCodecs();
|
||||
|
||||
for (int i = 0; i < properties->GetFileNames().size(); ++i) {
|
||||
const std::string& path = properties->GetFileNames()[i];
|
||||
if (this->DataScalarType == VTK_FLOAT)
|
||||
{
|
||||
void *imgData = nullptr;
|
||||
const std::string &path = properties->GetFileNames()[i];
|
||||
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user