Add dcm converter(BMP, PNG, JPG).
This commit is contained in:
@@ -5,20 +5,37 @@
|
||||
#include <QTextCodec>
|
||||
#include <QApplication>
|
||||
#include <QFont>
|
||||
#include "IO/Convert/DICOMToBMPConverter.h"
|
||||
#include "IO/Convert/DICOMToPNGConverter.h"
|
||||
#include "IO/Convert/DICOMToJPEGConverter.h"
|
||||
|
||||
#include "DIDMainWindow.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
QTextCodec* codec = QTextCodec::codecForName("GB2312");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
DICOMToBMPConverter converter;
|
||||
converter.setOutputSize(300, 300);
|
||||
converter.setFrame(2);
|
||||
converter.setInputDICOMFile("F:\\Kinds Data Files\\MultiFrame\\MultiFrame_Anon.dcm");
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QFont font;
|
||||
font.setFamily(QString::fromUtf8("Arial"));
|
||||
QApplication::setFont(font);
|
||||
|
||||
DIDMainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
converter.save("D:\\test.bmp");
|
||||
DICOMToPNGConverter pconverter;
|
||||
pconverter.setOutputSize(300, 300);
|
||||
pconverter.setInputDICOMFile("D:\\TestData\\CT\\4905\\a8c5c508-06b8-11ea-9b1e-509a4c8d26e3_08870001_4905_10903_287571");
|
||||
pconverter.save("D:\\test.png");
|
||||
DICOMToJPEGConverter jconverter;
|
||||
jconverter.setOutputSize(300, 300);
|
||||
jconverter.setInputDICOMFile("D:\\TestData\\CT\\4905\\a8c5c508-06b8-11ea-9b1e-509a4c8d26e3_08870001_4905_10903_287571");
|
||||
jconverter.save("D:\\test.jpg");
|
||||
// QTextCodec* codec = QTextCodec::codecForName("GB2312");
|
||||
// QTextCodec::setCodecForLocale(codec);
|
||||
//
|
||||
// QApplication a(argc, argv);
|
||||
//
|
||||
// QFont font;
|
||||
// font.setFamily(QString::fromUtf8("Arial"));
|
||||
// QApplication::setFont(font);
|
||||
//
|
||||
// DIDMainWindow w;
|
||||
// w.show();
|
||||
// return a.exec();
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ target_link_libraries(DIDKit dcm_network)
|
||||
add_dependencies(DIDKit dcm_network)
|
||||
|
||||
if(${BUILD_DIDKit_APP})
|
||||
add_executable(DIDKitApp ${DIDKit_headers} ${DIDKit_cpps} ${DIDKit_App_headers} ${DIDKit_App_cpps}
|
||||
add_executable(DIDKitApp ${DIDKit_IO_headers} ${DIDKit_IO_cpps} ${DIDKit_App_headers} ${DIDKit_App_cpps}
|
||||
${DIDKit_PACS_headers} ${DIDKit_PACS_cpps})
|
||||
target_link_libraries(DIDKitApp ${DCMTK_LIBRARIES})
|
||||
target_link_libraries(DIDKitApp ${VTK_LIBRARIES})
|
||||
|
||||
70
src/src/IO/Convert/ConverterBase.cpp
Normal file
70
src/src/IO/Convert/ConverterBase.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
|
||||
#include "ConverterBase.h"
|
||||
|
||||
#include <vtkImageData.h>
|
||||
#include <vtkImageResize.h>
|
||||
#include <vtkBMPWriter.h>
|
||||
#include <vtkNew.h>
|
||||
|
||||
#include "IO/DICOM/DICOMPixelDataHelper.h"
|
||||
|
||||
void ConverterBase::setOutputSize(int height, int width) {
|
||||
m_Size[0] = height;
|
||||
m_Size[1] = width;
|
||||
m_keepSize = false;
|
||||
}
|
||||
|
||||
void ConverterBase::setInputDICOMFile(const char *filename) {
|
||||
m_DICOMFileName = filename;
|
||||
}
|
||||
|
||||
void ConverterBase::loadDICOMPixelData() {
|
||||
if (! m_DICOMFileName.empty()){
|
||||
m_ImageData = vtkImageData::New();
|
||||
if (m_Frame<0){
|
||||
DICOMPixelDataHelper::GetRenderedData(m_DICOMFileName.c_str(),
|
||||
m_ImageData,m_Sample,m_Window[0],m_Window[1]);
|
||||
}
|
||||
else{
|
||||
DICOMPixelDataHelper::GetMultiFrameRenderedData(m_DICOMFileName.c_str(),
|
||||
m_ImageData,m_Frame,m_Sample,m_Window[0],m_Window[1]);
|
||||
}
|
||||
if (!m_keepSize){
|
||||
vtkNew<vtkImageResize>resize;
|
||||
resize->SetInputData(m_ImageData);
|
||||
resize->SetInterpolate(true);
|
||||
resize->SetResizeMethodToOutputDimensions();
|
||||
resize->SetOutputDimensions(m_Size[0],m_Size[1], -1);
|
||||
resize->Update();
|
||||
m_ImageData->DeepCopy(resize->GetOutput());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ConverterBase::setFileName(const char *filename) {
|
||||
m_OutputFileName = filename;
|
||||
}
|
||||
|
||||
ConverterBase::~ConverterBase() {
|
||||
if (m_ImageData){
|
||||
m_ImageData->Delete();
|
||||
m_ImageData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ConverterBase::setColorImage(int sample) {
|
||||
m_Sample = sample;
|
||||
}
|
||||
|
||||
void ConverterBase::setWindow(double windowLevel, double windowWidth) {
|
||||
m_Window[0] = windowLevel;
|
||||
m_Window[1] = windowWidth;
|
||||
}
|
||||
|
||||
void ConverterBase::setFrame(int frame) {
|
||||
m_Frame = frame;
|
||||
}
|
||||
41
src/src/IO/Convert/ConverterBase.h
Normal file
41
src/src/IO/Convert/ConverterBase.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
|
||||
#ifndef OMEGAV_CONVERTERBASE_H
|
||||
#define OMEGAV_CONVERTERBASE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class vtkImageData;
|
||||
class ConverterBase {
|
||||
public:
|
||||
ConverterBase() = default;
|
||||
virtual ~ConverterBase();
|
||||
void setOutputSize(int height, int width);
|
||||
void setInputDICOMFile(const char* filename);
|
||||
void setFileName(const char* filename);
|
||||
void setColorImage(int sample);
|
||||
void setWindow(double windowLevel, double windowWidth);
|
||||
void setFrame(int frame);
|
||||
virtual void save(const char* filename){};
|
||||
protected:
|
||||
void loadDICOMPixelData();
|
||||
int m_Size[2] = {100,100};
|
||||
double m_Window[2] = {128.0,256.0};
|
||||
int m_Sample = 1;
|
||||
int m_Frame = -1;
|
||||
std::string m_DICOMFileName;
|
||||
std::string m_OutputFileName;
|
||||
bool m_keepSize = true;
|
||||
vtkImageData* GetInputData(){
|
||||
return m_ImageData;
|
||||
}
|
||||
private:
|
||||
ConverterBase(const ConverterBase&) = delete;
|
||||
ConverterBase operator=(const ConverterBase&) = delete;
|
||||
vtkImageData* m_ImageData = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#endif //OMEGAV_CONVERTERBASE_H
|
||||
24
src/src/IO/Convert/DICOMToBMPConverter.cpp
Normal file
24
src/src/IO/Convert/DICOMToBMPConverter.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
#include "DICOMToBMPConverter.h"
|
||||
|
||||
#include "vtkNew.h"
|
||||
#include "vtkImageData.h"
|
||||
#include "vtkBMPWriter.h"
|
||||
|
||||
void DICOMToBMPConverter::save(const char *filename) {
|
||||
loadDICOMPixelData();
|
||||
vtkNew<vtkBMPWriter> writer;
|
||||
writer->SetInputData(GetInputData());
|
||||
writer->SetFileName(filename);
|
||||
writer->Update();
|
||||
}
|
||||
|
||||
DICOMToBMPConverter::DICOMToBMPConverter() {
|
||||
|
||||
}
|
||||
|
||||
DICOMToBMPConverter::~DICOMToBMPConverter() {
|
||||
|
||||
}
|
||||
18
src/src/IO/Convert/DICOMToBMPConverter.h
Normal file
18
src/src/IO/Convert/DICOMToBMPConverter.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
|
||||
#ifndef OMEGAV_DICOMTOBMPCONVERTER_H
|
||||
#define OMEGAV_DICOMTOBMPCONVERTER_H
|
||||
|
||||
#include "ConverterBase.h"
|
||||
|
||||
class DICOMToBMPConverter:public ConverterBase {
|
||||
public:
|
||||
DICOMToBMPConverter();
|
||||
~DICOMToBMPConverter();
|
||||
void save(const char* filename) override ;
|
||||
};
|
||||
|
||||
|
||||
#endif //OMEGAV_DICOMTOBMPCONVERTER_H
|
||||
26
src/src/IO/Convert/DICOMToJPEGConverter.cpp
Normal file
26
src/src/IO/Convert/DICOMToJPEGConverter.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
|
||||
#include "DICOMToJPEGConverter.h"
|
||||
|
||||
#include <vtkNew.h>
|
||||
#include <vtkImageData.h>
|
||||
#include <vtkJPEGWriter.h>
|
||||
|
||||
DICOMToJPEGConverter::DICOMToJPEGConverter() {
|
||||
|
||||
}
|
||||
|
||||
DICOMToJPEGConverter::~DICOMToJPEGConverter() {
|
||||
|
||||
}
|
||||
|
||||
void DICOMToJPEGConverter::save(const char *filename) {
|
||||
loadDICOMPixelData();
|
||||
vtkNew<vtkJPEGWriter> writer;
|
||||
writer->SetQuality(m_Quality);
|
||||
writer->SetInputData(GetInputData());
|
||||
writer->SetFileName(filename);
|
||||
writer->Write();
|
||||
}
|
||||
25
src/src/IO/Convert/DICOMToJPEGConverter.h
Normal file
25
src/src/IO/Convert/DICOMToJPEGConverter.h
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
|
||||
#ifndef OMEGAV_DICOMTOJPEGCONVERTER_H
|
||||
#define OMEGAV_DICOMTOJPEGCONVERTER_H
|
||||
#include "ConverterBase.h"
|
||||
|
||||
class DICOMToJPEGConverter: public ConverterBase {
|
||||
public:
|
||||
DICOMToJPEGConverter();
|
||||
~DICOMToJPEGConverter();
|
||||
void save(const char* filename) override;
|
||||
void setQuality(int quality){
|
||||
if (quality<0) quality = 0;
|
||||
if (quality>100) quality = 100;
|
||||
m_Quality = quality;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_Quality = 100;
|
||||
};
|
||||
|
||||
|
||||
#endif //OMEGAV_DICOMTOJPEGCONVERTER_H
|
||||
25
src/src/IO/Convert/DICOMToPNGConverter.cpp
Normal file
25
src/src/IO/Convert/DICOMToPNGConverter.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
|
||||
#include "DICOMToPNGConverter.h"
|
||||
#include "vtkNew.h"
|
||||
#include "vtkImageData.h"
|
||||
#include "vtkPNGWriter.h"
|
||||
|
||||
DICOMToPNGConverter::DICOMToPNGConverter() {
|
||||
|
||||
}
|
||||
|
||||
DICOMToPNGConverter::~DICOMToPNGConverter() {
|
||||
|
||||
}
|
||||
|
||||
void DICOMToPNGConverter::save(const char *filename) {
|
||||
loadDICOMPixelData();
|
||||
vtkNew<vtkPNGWriter> writer;
|
||||
writer->SetCompressionLevel(m_CompressionLevel);
|
||||
writer->SetInputData(GetInputData());
|
||||
writer->SetFileName(filename);
|
||||
writer->Write();
|
||||
}
|
||||
26
src/src/IO/Convert/DICOMToPNGConverter.h
Normal file
26
src/src/IO/Convert/DICOMToPNGConverter.h
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by Krad on 2022/9/21.
|
||||
//
|
||||
|
||||
#ifndef OMEGAV_DICOMTOPNGCONVERTER_H
|
||||
#define OMEGAV_DICOMTOPNGCONVERTER_H
|
||||
|
||||
#include "ConverterBase.h"
|
||||
|
||||
class DICOMToPNGConverter:public ConverterBase {
|
||||
public:
|
||||
DICOMToPNGConverter();
|
||||
~DICOMToPNGConverter();
|
||||
void save(const char* filename) override;
|
||||
void setCompressLevel(int level){
|
||||
if (level<0) level = 0;
|
||||
if (level>9) level = 9;
|
||||
m_CompressionLevel = level;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_CompressionLevel = 5;
|
||||
};
|
||||
|
||||
|
||||
#endif //OMEGAV_DICOMTOPNGCONVERTER_H
|
||||
@@ -3,12 +3,15 @@
|
||||
//
|
||||
|
||||
#include "DICOMPixelDataHelper.h"
|
||||
|
||||
#include <dcmtk/dcmdata/dcrledrg.h>
|
||||
#include <dcmtk/dcmjpeg/djdecode.h>
|
||||
#include <dcmtk/dcmjpls/djdecode.h>
|
||||
#include <dcmtk/dcmdata/dcfilefo.h>
|
||||
#include <dcmtk/dcmimgle/dcmimage.h>
|
||||
#include <dcmtk/dcmimgle/dipixel.h>
|
||||
#include <vtkImageData.h>
|
||||
|
||||
#include "ExtendMedicalImageProperties.h"
|
||||
#ifdef OPENJPEG
|
||||
#include "openjpeg-2.3/openjpeg.h"
|
||||
@@ -248,3 +251,47 @@ void DICOMPixelDataHelper::ClearFileObjectCache() {
|
||||
bool DICOMPixelDataHelper::CheckFileObjectCache(const char *path) {
|
||||
return DICOMFileObjectCache::getInstance()->contains(path);
|
||||
}
|
||||
|
||||
bool DICOMPixelDataHelper::GetRenderedData(const char *path, vtkImageData *data,int sample,double windowLevel, double windowWidth) {
|
||||
DcmFileFormat fileFormat;
|
||||
if (fileFormat.loadFile(path).good()) {
|
||||
DcmDataset *dset = fileFormat.getDataset();
|
||||
DicomImage dcmImage(&fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
|
||||
RenderToImageData(data, sample, windowLevel, windowWidth, dcmImage);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DICOMPixelDataHelper::RenderToImageData(vtkImageData *data, int sample, double windowLevel, double windowWidth,
|
||||
DicomImage &dcmImage) {//flip for vtk writer
|
||||
dcmImage.flipImage(0,1);
|
||||
if (sample == 1){
|
||||
dcmImage.setWindow(windowLevel, windowWidth);
|
||||
}
|
||||
data->SetExtent(0, dcmImage.getWidth()-1,0,dcmImage.getHeight()-1, 0 ,0);
|
||||
data->AllocateScalars(VTK_UNSIGNED_CHAR,3);
|
||||
void* d = data->GetScalarPointer();
|
||||
dcmImage.createWindowsDIB(d,dcmImage.getWidth()*dcmImage.getHeight()*3 );
|
||||
}
|
||||
|
||||
bool DICOMPixelDataHelper::GetMultiFrameRenderedData(const char *path, vtkImageData *data, int sample, int frame,
|
||||
double windowLevel, double windowWidth) {
|
||||
auto fileFormat = DICOMFileObjectCache::getInstance()->GetFileObject(path);
|
||||
if (!fileFormat){
|
||||
fileFormat = new DcmFileFormat;
|
||||
if (fileFormat->loadFile(path).good() && fileFormat->loadAllDataIntoMemory().good()) {
|
||||
DICOMFileObjectCache::getInstance()->store(path,fileFormat);
|
||||
DicomImage dcmImage(fileFormat, fileFormat->getDataset()->getOriginalXfer(), CIF_UsePartialAccessToPixelData,
|
||||
frame, 1);
|
||||
if (dcmImage.getStatus() == EIS_Normal) {
|
||||
RenderToImageData(data, sample, windowLevel, windowWidth, dcmImage);
|
||||
delete fileFormat;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete fileFormat;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
#ifndef OMEGAV_DICOMPIXELDATAHELPER_H
|
||||
#define OMEGAV_DICOMPIXELDATAHELPER_H
|
||||
|
||||
class ExtendMedicalImageProperties;
|
||||
#include <dcmtk/dcmimgle/dcmimage.h>
|
||||
|
||||
class ExtendMedicalImageProperties;
|
||||
class vtkImageData;
|
||||
/**
|
||||
* DICOM file Pixel Data read helper
|
||||
*/
|
||||
@@ -18,6 +20,9 @@ public:
|
||||
}
|
||||
static void GetThumbnailData(ExtendMedicalImageProperties *property, void*& data,
|
||||
unsigned long& length,int& sample);
|
||||
|
||||
static bool GetRenderedData(const char * path, vtkImageData* data, int sample, double windowLevel, double windowWidth);
|
||||
static bool GetMultiFrameRenderedData(const char * path, vtkImageData* data, int sample,int frame, double windowLevel, double windowWidth);
|
||||
/**
|
||||
* Get Pixel Data with Rescaled, result is calculate as integer, and arrange as integer.
|
||||
* @param path dcm file absolute path
|
||||
@@ -97,6 +102,9 @@ public:
|
||||
* Finalize decompress Codecs, must be called after other method have done.
|
||||
*/
|
||||
static void FinalizeCodecs();
|
||||
|
||||
static void
|
||||
RenderToImageData(vtkImageData *data, int sample, double windowLevel, double windowWidth, DicomImage &dcmImage);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user