簡單的Dicom圖像顯示和保存的方法(利用dcmtk庫和opencv庫)

視頻教程:一種簡單的Dicom圖像顯示和保存的方法(利用dcmtk庫和opencv庫)

Git: https://github.com/JasonLiThirty/Dicom

opencv的下載

Dicom_Module工程配置opencv庫

  • 配置系統(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,這兩個lib文件在opencv\build\x64\vc14\lib下。
  • 將opencv\build\x64\vc14\bin目錄下的opencv_world430.dll和opencv_world430d.dll拷貝到工程的輸出目錄下。

Dicom_Module工程配置dcmimgle和dcmimage庫

  • 在工程配置的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;
...
}

實現(xiàn)類DicomProcessor

  • 新增顯示圖像和保存圖像為BMP的實現(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;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容