Qt5使用QGrahicsView显示Dicom图像

一、首先,显示结果。Qt5使用QGrahicsView显示Dicom图像_第1张图片

二、程序

1、所需头文件

#include 
#include "ui_DicomToMat.h"

#include "itkImageFileReader.h"
#include "itkGDCMImageIO.h"
#include "itkOpenCVImageBridge.h"

#include "opencv2/opencv.hpp"

#include 

2、cpp代码

        首先设置读取Dicom的基本属性,都是老套路。需要注意的是这里官方给出的读取图片的IputPixType是unsined short 型,本例中使用unsingned char型,与后面创建QImage的最后一个参数QImage::Format_Indexed8相匹配,具体原因后文详细说明。读取到图片数据后,通过cv::Mat S_OrgImg = itk::OpenCVImageBridge::ITKImageToCVMat< OutputImageType >(reader->GetOutput());将其转换成openCV的Mat格式,然后使用Mat里的数据初始化一个QImage的变量并将其显示在GraphicsView中。

DicomToMat::DicomToMat(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
	//读取基本套路  注意 unsigned char 后文会提及
	typedef unsigned char InputPixelType;//char 8位 short 16位  int32位
	typedef unsigned char OutputPixelType;
	const unsigned int InputDimension = 2;
	typedef itk::Image< InputPixelType, InputDimension > InputImageType;
	typedef itk::Image< OutputPixelType, InputDimension> OutputImageType;
	typedef itk::ImageFileReader< InputImageType > ReaderType;
	ReaderType::Pointer reader = ReaderType::New();

	std::string fileName = "D:/vs2019WorkPlace/test01/test01/DICOMtest/20200317143429.dcm";

	reader->SetFileName(fileName);

	typedef itk::GDCMImageIO           ImageIOType;
	ImageIOType::Pointer gdcmImageIO = ImageIOType::New();
	reader->SetImageIO(gdcmImageIO);

	try
	{
		reader->Update();
	}
	catch (itk::ExceptionObject & e)
	{
		std::cerr << "exception in file reader " << std::endl;
		std::cerr << e << std::endl;
		return ;
	}
	//将itk读出的图像数据转换为Mat格式
	cv::Mat S_OrgImg = itk::OpenCVImageBridge::ITKImageToCVMat< OutputImageType >(reader->GetOutput());
	/*qDebug() << S_OrgImg.type();//CV_8U  1 个通道       
	qDebug() << S_OrgImg.channels();*/
	//将Mat格式的数据存入QImage中
	QImage q_img(S_OrgImg.data, S_OrgImg.cols, S_OrgImg.rows, S_OrgImg.step, QImage::Format_Indexed8);
	QPixmap pixmap = QPixmap::fromImage(q_img);
	//QgraphicsScene显示 pixmap
	QGraphicsScene *scene = new QGraphicsScene();
	ui.View->setScene(scene);
	ui.View->setBackgroundBrush(QBrush(Qt::black));

	QGraphicsPixmapItem *pixItem = new QGraphicsPixmapItem;
	scene->addItem(pixItem);
	pixItem->setPixmap(pixmap);

}

 三、遇到的困难

一开始使用官方给的读取例子。

参见:D:\ITK\InsightToolkit-4.13.3\Examples\IO\DicomImageReadWrite.cxx

 typedef signed short InputPixelType;
  const unsigned int   InputDimension = 2;

  typedef itk::Image< InputPixelType, InputDimension > InputImageType;

使用的是signed short 定义的InputPixelType,也就是16位的数据。将读取的结果转换成Mat格式格,读取获得Mat格式图像的type()和channels(),结果是type()=3,channels()=1。根据openCV的Mat格式表3对应的是CV_16S也就是和QImage的最后一个参数QImage::Format_Indexed8匹配。

关于Mat格式参考:Mat数据格式_Rareay的博客-CSDN博客_mat格式

//将itk读出的图像数据转换为Mat格式
	cv::Mat S_OrgImg = itk::OpenCVImageBridge::ITKImageToCVMat< OutputImageType >(reader->GetOutput());
	qDebug() << S_OrgImg.type();//CV_8U  1 个通道       
	qDebug() << S_OrgImg.channels();
	//将Mat格式的数据存入QImage中
	QImage q_img(S_OrgImg.data, S_OrgImg.cols, S_OrgImg.rows, S_OrgImg.step, QImage::Format_Indexed8);

从而导致显示的图像为:Qt5使用QGrahicsView显示Dicom图像_第2张图片

图像的左右只显示一半,而且上下的行像素应该是奇偶只显示一种。 

最终选择Dicom的读取类型为unsigned char,读出的Mat图像的type()=0,也就是CV_8U,和程序后面的QImage型匹配。

最后还有几个问题,改变QImage的类型而不改变Dicom图像的读取类型?如果可以改成什么?

什么决定了Dicom的读取类型?为什么用singned short 和 unsigned char 都可以读出来?

你可能感兴趣的:(Dicom图像显示,visual,studio,c++,qt)