視頻教程:一種簡(jiǎn)單的Dicom圖像顯示和保存的方法(利用dcmtk庫(kù)和opencv庫(kù))
Git: https://github.com/JasonLiThirty/Dicom
opencv的下載
- 官網(wǎng):https://opencv.org/releases/,下載最新版本4.3.0
- 安裝即解壓:
Dicom_Module工程配置opencv庫(kù)
- 配置系統(tǒng)的環(huán)境變量Path:把之前解壓(安裝)好的opencv路徑下的x64的bin路徑添加到Path系統(tǒng)環(huán)境變量中誓琼,重啟检激。
- 在Dicom_Module工程配置中加入opencv的include路徑和lib路徑。
- 在工程配置的linker->input里加入opencv的依賴lib腹侣,Debug配置opencv_world430d.lib叔收,Relase配置opencv_world430.lib,這兩個(gè)lib文件在opencv\build\x64\vc14\lib下傲隶。
- 將opencv\build\x64\vc14\bin目錄下的opencv_world430.dll和opencv_world430d.dll拷貝到工程的輸出目錄下饺律。
Dicom_Module工程配置dcmimgle和dcmimage庫(kù)
- 在工程配置的linker->input里加入dcmimgle和dcmimage的依賴lib
-
將最先編譯出的DCMTK類包中bin目錄下的dcmimgle.dll和dcmimage.dll拷貝到工程的輸出目錄下。
Dicom_Module工程里編寫所需類和函數(shù)
接口類DicomIF
- 新增顯示圖像和保存圖像為BMP的接口
class __declspec(dllexport) IDicom
{
public:
...
virtual bool ShowImage(std::string filePath, Image_Pattern pattern = ImagePattern_Normal, signed int degree = 0) = 0;
virtual bool SavetoBMP(std::string filePath, Image_Pattern pattern = ImagePattern_Normal, signed int degree = 0) = 0;
...
}
實(shí)現(xiàn)類DicomProcessor
- 新增顯示圖像和保存圖像為BMP的實(shí)現(xiàn)(頭文件包含dcmimage.h)
#include "dcmtk/dcmimgle/dcmimage.h"
bool ShowImage(std::string filePath, Image_Pattern pattern = ImagePattern_Normal, signed int degree = 0);
bool SavetoBMP(std::string filePath, Image_Pattern pattern = ImagePattern_Normal, signed int degree = 0);
bool DicomProcessor::ShowImage(std::string filePath, Image_Pattern pattern, signed int degree)
{
if (!Read(filePath))
{
std::cout << "Read Dicom File Failed: " << filePath.c_str() << std::endl;
return false;
}
E_TransferSyntax tfs = m_fileformat.getDataset()->getOriginalXfer();
DicomImage *pImage = new DicomImage(&m_fileformat, tfs);
pImage->setWindow(m_image->WindowCenter, m_image->WindowWidth);
PatternConversion(pImage, pattern, degree);
Uint16 *pixelData = (Uint16*)(pImage->getOutputData(m_image->BitsAllocated));
if (pixelData == NULL)
{
std::cout << "Get Image Data Failed: " << filePath.c_str() << std::endl;
return false;
}
cv::Mat dst(pImage->getWidth(), pImage->getHeight(), CV_16U, pixelData);
cv::imshow(m_patient->PatientsName, dst);
cv::waitKey(0);
return true;
}
bool DicomProcessor::SavetoBMP(std::string filePath, Image_Pattern pattern, signed int degree)
{
if (!Read(filePath))
{
std::cout << "Read Dicom File Failed: " << filePath.c_str() << std::endl;
return false;
}
E_TransferSyntax tfs = m_fileformat.getDataset()->getOriginalXfer();
DicomImage *pImage = new DicomImage(&m_fileformat, tfs);
pImage->setWindow(m_image->WindowCenter, m_image->WindowWidth);
PatternConversion(pImage, pattern, degree);
if (!pImage->writeBMP(GenerateImageName(filePath, pattern).c_str(), 8))
{
std::cout << "Read Dicom File Failed: " << filePath.c_str() << std::endl;
return false;
}
return true;
}
- 新增圖像變換函數(shù)
void PatternConversion(DicomImage* &image, Image_Pattern pattern, signed int degree = 0);
void DicomProcessor::PatternConversion(DicomImage* &image, Image_Pattern pattern, signed int degree)
{
switch (pattern)
{
case ImagePattern_Normal:
break;
case ImagePattern_Flip:
image->flipImage();
break;
case ImagePattern_Rotate:
image->rotateImage(degree);
break;
case ImagePattern_Polarity:
image->setPolarity(EPP_Reverse);
break;
default:
break;
}
}
DicomInfo:加入圖像變換類型定義
enum Image_Pattern
{
ImagePattern_Normal = 1,
ImagePattern_Flip,
ImagePattern_Rotate,
ImagePattern_Polarity
};
DicomUtils:加入生成BMP文件名的函數(shù)
__declspec(dllexport) std::string GenerateImageName(std::string name, Image_Pattern pattern);
std::string GenerateImageName(std::string name, Image_Pattern pattern)
{
std::string prefix = "";
switch (pattern)
{
case ImagePattern_Normal:
break;
case ImagePattern_Flip:
prefix = "_flip";
break;
case ImagePattern_Rotate:
prefix = "_rotate";
break;
case ImagePattern_Polarity:
prefix = "_polarity";
break;
default:
break;
}
auto last_pos = name.find_last_of(".");
std::string srcName = name.substr(0, last_pos);
std::cout << srcName << std::endl;
std::string fileName = srcName + prefix + ".bmp";
return fileName;
}
Dicom_Sample加入調(diào)用代碼
int main()
{
CreateDicomProcessor();
std::string readFile = "E:\\Learning\\DICOM\\Module_Sample\\MRBRAIN.dcm";
//if (!GetDicomProcessor()->ShowImage(readFile, ImagePattern_Flip))
//if (!GetDicomProcessor()->ShowImage(readFile, ImagePattern_Rotate, 90));
//if (!GetDicomProcessor()->ShowImage(readFile, ImagePattern_Polarity))
if (!GetDicomProcessor()->ShowImage(readFile))
{
std::cout << "Read Dicom Image Failed: " << readFile.c_str() << std::endl;
return -1;
}
if (!GetDicomProcessor()->SavetoBMP(readFile))
//if (!GetDicomProcessor()->SavetoBMP(readFile, ImagePattern_Flip))
//if (!GetDicomProcessor()->SavetoBMP(readFile, ImagePattern_Rotate, 90))
//if (!GetDicomProcessor()->SavetoBMP(readFile, ImagePattern_Polarity))
{
std::cout << "Read Dicom Image Failed: " << readFile.c_str() << std::endl;
return -1;
}
DeleteDicomProcessor();
return 0;
}