DICOM笔记-Qt读取JPEG格式DICOM文件

  在之前笔记中使用VS读取了JPEG格式的DICOM文件DICOM笔记-解析JPEG压缩格式DCM文件
  现在使用Qt写一个读取DICOM文件的Demo;

代码

  在Qt的pro文件中增加DCMTK库的头文件和lib文件所在位置以及lib名称;

INCLUDEPATH+="G:/DCMTK-3.6.6/out-vs2017-win32/Debug/include/"
LIBS+= -L$$quote("G:/DCMTK-3.6.6/out-vs2017-win32/Debug/lib/")
LIBS+=cmr.lib\
	dcmdata.lib\
	dcmdsig.lib\
	dcmect.lib\
	dcmfg.lib\
	dcmimage.lib\
	dcmimgle.lib\
	dcmiod.lib\
	dcmjpeg.lib\
	dcmjpls.lib\
	dcmnet.lib\
	dcmpmap.lib\
	dcmpstat.lib\
	dcmqrdb.lib\
	dcmrt.lib\
	dcmseg.lib\
	dcmsr.lib\
	dcmtkcharls.lib\
	dcmtls.lib\
	dcmtract.lib\
	dcmwlm.lib\
	i2d.lib\
	ijg12.lib\
	ijg16.lib\
	ijg8.lib\
	oflog.lib\
	ofstd.lib

  在MainWindow.h中增加相应打开QAction的槽函数on_actionOpen_triggered;

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    void ConvertDigitImageToGrayImageByWindowLevelAndWindowWidth(short* digitImage, short* grayImage, int size, int window_level, int window_width);
private slots:
    void on_actionOpen_triggered();
private:
    Ui::MainWindow *ui;
    QString dcm_file_path;
};
#endif // MAINWINDOW_H

  在打开对应的QAction的槽函数on_actionOpen_triggered中增加读取解析DICOM功能;
    1.读取DICOM文件的宽和高;
    2.解码JPEG格式;
    3.在QLabel下显示图像;

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <iostream>
#include "dcmtk\config\osconfig.h"
#include "dcmtk\dcmdata\dctk.h"
#include <dcmtk/dcmjpeg/djdecode.h>  /* for dcmjpeg decoders */
#include <dcmtk/dcmjpeg/djencode.h>
#include <dcmtk/dcmjpls/djdecode.h>		//for JPEG-LS decode
#include <dcmtk/dcmjpls/djencode.h>		//for JPEG-LS encode
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow){
    ui->setupUi(this);
}

MainWindow::~MainWindow(){
    delete ui;
}

void MainWindow::on_actionOpen_triggered(){
    this->dcm_file_path = QFileDialog::getOpenFileName(this,tr("选择DICOM图像"),"",tr("Files (*.dcm )"));

    DJDecoderRegistration::registerCodecs();
    DJLSEncoderRegistration::registerCodecs();		//JPEG-LS encoder registerCodecs
    DJLSDecoderRegistration::registerCodecs();		//JPEG-LS decoder registerCodecs

    DcmFileFormat *myFileFormat = new DcmFileFormat;
    OFCondition cond = myFileFormat->loadFile(dcm_file_path.toStdString().c_str());

    Uint16 height = 0;
    Uint16 width = 0;
    if (cond.good()){
        if (myFileFormat->getDataset()->findAndGetUint16(DCM_Rows, height).bad()) {
            std::cout << "No Row Data!\n";
        }
        if (myFileFormat->getDataset()->findAndGetUint16(DCM_Columns, width).bad()) {
            std::cout << "No Columns Data!\n";
        }
    }

    unsigned long size = 0;
    int all_point_size = height * width;
    short* pix_buf = new short[all_point_size];

    DcmElement* pElement = nullptr;
    myFileFormat->getDataset()->chooseRepresentation(EXS_DeflatedLittleEndianExplicit, NULL);
    myFileFormat->getDataset()->findAndGetElement(DCM_PixelData, pElement);
    if (pElement != NULL) {
        size = pElement->getLength()/2;
        OFCondition cond = pElement->loadAllDataIntoMemory();
        if (cond.good()) {
            Uint16 * ptr;
            cond = pElement->getUint16Array(ptr);
            if (cond.good()) {
                ConvertDigitImageToGrayImageByWindowLevelAndWindowWidth((short*)ptr, pix_buf, size, 400, 2000);
            }
        }
    }

    char* pBuf = new char[all_point_size]{0};
    int single_row_size = width;
    for (int i = 0; i< height;i++){
        char* row_ptr = pBuf+i*single_row_size;
        for (int j = 0; j < width; j++) {
            row_ptr[j] = pix_buf[i*width+j];
        }
    }
    QImage images = QImage((uchar*)pBuf, width, height, QImage::Format_Indexed8);
    ui->label->setPixmap(QPixmap::fromImage(images));
    delete[] pBuf;
    delete[] pix_buf;
    DJEncoderRegistration::cleanup();
	DJDecoderRegistration::cleanup();
	DJLSEncoderRegistration::cleanup();		//JPEG-LS encoder cleanup
	DJLSDecoderRegistration::cleanup();		//JPEG-LS decoder cleanup
}
void MainWindow::ConvertDigitImageToGrayImageByWindowLevelAndWindowWidth(short* digitImage, short* grayImage,
         int size, int window_level, int window_width){
    double rate = 256.0 / window_width;
    for (int i = 0; i < size; i++){
        int tmp = 128.0 + (digitImage[i] - window_level)*rate;
        if (tmp < 0){
            tmp = 0;
        }
        else if (tmp > 255){
            tmp = 255;
        }
        grayImage[i] = tmp;
    }
}

在这里插入图片描述

  代码以及项目所在位置:打开JEPG格式DICOM文件的DemoMyDicom.rar

知识点

QString转换char*

  先将 QString 转为标准库中的 string 类型,然后将 string 转为 char *。

QString  filename;
std::string str = filename.toStdString();
const char* ch = str.c_str();

二维数据矩阵转换图像

  先将二维数组转换为QImage对象,然后调用QPixmap::fromImage函数生成QPixmap对象;

QImage images = QImage((uchar*)pBuf, 512, 512, QImage::Format_Indexed8);
ui->label->setPixmap(QPixmap::fromImage(images));

参考资料

1.QT 二维数组转BMP BMP转二维数组 QImage转二维数组 的简便方法
2.QT显示图片的几种方法
3.文件数据通过qt将二维数组中的像素点显示成一张图片
4.QString 转换为 char *

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑山老妖的笔记本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值