视频教程:https://www.bilibili.com/video/av84165974
图像归一化涉及的DICOM_Tag
图像归一化的计算流程
图像归一化函数
void DicomProcessor::FillNormalizeImage(unsigned char* data)
{
//m_image->SamplesPerPixel = 1;
//m_image->BitsAllocated = 16;
//m_image->BitsStored = 12;
//m_image->HighBit = 11;
FillInfo(DCM_SamplesPerPixel, std::to_string(m_image->SamplesPerPixel));
FillInfo(DCM_PhotometricInterpretation, m_image->PhotometricInterpretation);
FillInfo(DCM_Rows, std::to_string(m_image->Rows));
FillInfo(DCM_Columns, std::to_string(m_image->Columns));
FillInfo(DCM_BitsAllocated, std::to_string(m_image->BitsAllocated));
FillInfo(DCM_BitsStored, std::to_string(m_image->BitsStored));
FillInfo(DCM_HighBit, std::to_string(m_image->HighBit));
FillInfo(DCM_PixelRepresentation, std::to_string(m_image->PixelRepresentation));
//number of image pixels
int64_t dataNumber = m_image->Rows * m_image->Columns;
std::shared_ptr<float> pData(new float[dataNumber]);
float minData = 0.0;
float maxData = 0.0;
//Get max * min data(float32)
for (int64_t i = 0, j = 0; i < dataNumber; i++, j += 4)
{
memcpy(pData.get() + i, data + j, 4);
minData = (*(pData.get() + i) < minData) ? *(pData.get() + i) : minData;
maxData = (*(pData.get() + i) > maxData) ? *(pData.get() + i) : maxData;
}
//Get the range of normalization
uint32_t range = (2 << (m_image->BitsStored - 1)) - 1; //BitsStored = 12 -> range = 4095
//Get Rescale Slope and Rescale Intercept
m_image->RescaleIntercept = minData;
m_image->RescaleSlope = (maxData - minData) / range;
//Get Window Center and Window Width
m_image->WindowCenter = maxData / 2;
m_image->WindowWidth = maxData;
//Normalization(Float32 to Uint16), BitsAllocated = 16 -> Create unsigned int16 array
std::shared_ptr<uint16_t> pNormalizedData(new uint16_t[dataNumber]());
for (int64_t i = 0; i < dataNumber; i++)
{
//normalizedData = (srcData - rescale intercept) / rescale slope
pNormalizedData.get()[i] = (uint16_t)((pData.get()[i] - m_image->RescaleIntercept) / m_image->RescaleSlope);
}
//Save normalized data
OFCondition status = m_fileformat.getDataset()->putAndInsertUint16Array(DCM_PixelData, pNormalizedData.get(), dataNumber);
if (!status.good())
{
std::cout << "Fill pixel data error:" << status.text() << std::endl;
}
//Save Fields invloved
FillInfo(DCM_RescaleIntercept, std::to_string(m_image->RescaleIntercept));
FillInfo(DCM_RescaleSlope, std::to_string(m_image->RescaleSlope));
FillInfo(DCM_WindowCenter, std::to_string(m_image->WindowCenter));
FillInfo(DCM_WindowWidth, std::to_string(m_image->WindowWidth));
}