QImage从VtkImageData中加载16图片 导出PNG格式
项目背景:
1.前后端采用websocket通讯,后端处理得到的结果通过png数据格式返回前端
2.常规的8位png图像只能由256个灰阶,动态范围小,不能在前端进行窗宽窗位调节,因此需要使用16png数据
3.使用VTK 从nrrd/Dicom/nifty格式中解析图像数据解析得到的数据通常为16有符号类型,signed short,VtkImageData->QImage->png
处理方式:
1.先使用vtkNrrdReader读取nrrd数据
vtkSmartPointer <vtkNrrdReader> reader = vtkSmartPointer<vtkNrrdReader>::New();
reader->SetFileName(nrrdFileName.c_str());
reader->Update();
m_imageData = reader->GetOutput();
2.数据灰度偏移处理
需要注意的是,1中得到的数据格式为VTK_SHORT类型,但是png是没有有符号数据的概念,也就是png中存储的均为正数,因此需要先对数据进行处理,VTK_SHORT->VTK_UNSIGNED_SHORT。
使用vtkImageShiftScale。
double range[2];
data->GetScalarRange(range);//获取data的最大最小像素值
vtkImageShiftScale* shifter = vtkImageShiftScale::New();
shifter->SetShift(-1.0 * range[0]); //减去最小值
shifter->SetOutputScalarTypeToUnsignedShort();
shifter->SetInputData(data);
shifter->Update();
注意:如果需要将数据转成8位无符号数据,即VTK_UNSIGNED_CHAR,可对原始图像进行动态范围的缩放,即将灰度范围放缩到0-255区间,利用scale函数
shifter->SetScale(255.0 / (range[1] - range[0]));
shifter->SetOutputScalarTypeToUnsignedChar();
3.将2中处理好的数据用QImage类表示
vtkSmartPointer<vtkImageData> castdata = shifter->GetOutput();
uchar* newMipData = (unsigned char*)castdata->GetScalarPointer();
QImage tmpImg(newMipData, castdata->GetDimensions()[0], castdata->GetDimensions()[1], castdata->GetDimensions()[0] * sizeof(quint16), QImage::Format_Grayscale16);
4.将3中的QImage保存为png格式即可
QByteArray imgData; QBuffer tmpBuf(&imgData); tmpBuf.open(QIODevice::WriteOnly); img.save(&tmpBuf, "png");
img.save(QString::fromStdString("D:/1.png"), "png");
接下来即可将png格式的数据流(imgData, QByteArray)通过qwebsocket发出去了。
注意通过此方法保存png图像时,可以通过quality参数调节保存需要的耗时:
bool QImage::save ( const QString & fileName, const char * format = 0, int quality = -1 ) const
quality | file size | speed |
---|---|---|
0 | smallest | slowest |
100 | largest | fastest |
“The above quote can be re-expressed in the following table which indicates that you need to set quality to 100 to achieve the fastest conversion at the expense of producing the largest file size:”
参考博文:
https://stackoverflow.com/questions/27035006/what-is-the-fastest-way-to-save-a-qimage-object-into-an-image-file
下图即为保存得到的16-bit的png图像
\