读取并可视化DICOM图像(VTK & OpenCV)
来源:互联网 发布:linux 查找关键字 编辑:程序博客网 时间:2024/06/08 11:26
本人最近刚完成一个项目的一部分程序的编写。项目主要工作是将CT实时显示,而CT成像较为缓慢,因此首先的步骤就是将CT图转为超声图。简单来说,本人完成的工作就是将CT图转为超声图,并保存下来。
工作思路
整个工作,最难的就是CT图的正确读取。本人处理的CT图的格式是DICOM格式,这个用OpenCV不能直接读取,我采用了VTK进行读取,然后用OpenCV处理的思路(当然网上也有人说可以直接用ITK读取并处理,只是我不熟悉ITK,所以没有用它)。
DICOM图像的读取
其实读取DICOM图像不难,主要的要注意在使用VTK读取的时候,要记得转换数据类型,要使用imagecast转到double(或float)型,这样像素值出来的才是正确的,这样在转到OpenCV上,就可以使用OpenCV显示并处理,最后写入(保存)。
使用OpenCV的原因
因为OpenCV简单,处理图像起来比VTK简单很多,显示图片也不需要理解VTK中的管线等概念。
程序实现
实现平台:Win10,C++,Microsoft Visual Studio 2010
VTK5.6,OpenCV 2.4.10
#include <iostream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <vtkSmartPointer.h>#include <vtkImageViewer2.h>#include <vtkImageCast.h>#include <vtkDICOMImageReader.h>#include <vtkRenderWindow.h>#include <vtkRenderWindowInteractor.h>#include <vtkRenderer.h>#include <vtkImageData.h>#include <vtkCoordinate.h>using namespace cv;using namespace std;// 读入一个CT图,返回它的像素矩阵,使用OpenCV的Mat类型返回void dicomread(string inputFilename, Mat &img,vtkSmartPointer<vtkDICOMImageReader> &reader){ img.create(512,512,CV_32SC1); vtkSmartPointer<vtkImageCast> imageCast = vtkSmartPointer<vtkImageCast>::New(); reader->SetFileName(inputFilename.c_str()); reader->Update(); imageCast->SetInputConnection(reader->GetOutputPort()); imageCast->SetOutputScalarTypeToInt(); imageCast->Update(); // 图像的基本信息 int dims[3]; reader->GetOutput()->GetDimensions(dims); //图像的像素值 for(int k=0;k<dims[2];k++) { for(int j=0;j<dims[1];j++) { for(int i=0;i<dims[0];i++) { int* pixel = (int*)(imageCast->GetOutput()->GetScalarPointer(i,j,k)); // 第i列第j行的像素值 img.at<int>(j,i) = int(*pixel); // 第j行第i列的像素值 } } }}
这个就是使用VTK读取DICOM图像并将像素值转给OpenCV的Mat对象的程序,程序运行后,会传出一个Mat对象,和一个VTK的Reader对象(这个没有作用,只是可以保存下来,如果有操作需要VTK的时候才有用)。然后,我显示了一下得到的Mat对象的信息。
#include <iostream>#include <string>#include <vector>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <vtkSmartPointer.h>#include <vtkImageViewer2.h>#include <vtkDICOMImageReader.h>#include <vtkRenderWindow.h>#include <vtkRenderWindowInteractor.h>#include <vtkRenderer.h>using namespace std;using namespace cv;extern void dicomread(string inputFilename, Mat &img,vtkSmartPointer<vtkDICOMImageReader> &reader);int main(){ string filename = "D:\\CT\\CT000895"; Mat I1,G1; vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New(); // 读入dicom图 dicomread(filename,I1,reader); flip(I1,I1,0); cout << I1.channels() << " " << I1.size() << endl;}
运行结果:
结果显示:图像是单信道的,大小为512×512
可视化DICOM图像
DICOM图像比较特殊,不能直接使用imshow()函数去可视化,需要进行简单的处理。直接上程序,
void showdicom(Mat I){ double maxx=0,minn=0; double *max = &maxx; double *min = &minn; I.convertTo(I,CV_64FC1); minMaxIdx(I,min,max); for(int i=0;i<I.rows;i++) { for(int j=0;j<I.cols;j++) { I.at<double>(i,j) = 255*(I.at<double>(i,j)-minn)*1/(maxx-minn); } } imshow("DICOM Image",I); waitKey(0);}
运行测试结果:
至此,成功读取并可视化DICOM图像。
项目文件:http://download.csdn.net/detail/louishao/9876308
- 读取并可视化DICOM图像(VTK & OpenCV)
- VTK读取DICOM图像
- ITK&&VTK读取DICOM数据并渲染
- 3 vtk读取并显示dicom文件
- VTK三维重建(1)-使用VTK读取DICOM,并动态输出
- ITK+VTK+QT 读取DICOM序列图像遇到的问题(1)
- 读取DICOM图像,3D可视化,手动分割,获得特征值
- Vtk读取并显示保存图像
- VTK读取序列的Dicom医学图片,用Marchingcube进行重建,并保存为obj文件
- ITK/VTK对DICOM文件的读取
- VTK学习(三)VTK读取序列图像
- VTK读取序列图像
- vtk读取序列医学Dicom图片进行体绘制(vtkVolumeRayCastCompositeFunction类)
- OpenCV 读取文件并转换灰度图像
- opencv读取序列图像并显示
- opencv 读取图像区域 并 计算HOG
- Python OpenCV 读取并显示图像
- 使用vtk面绘制dicom医学断层图像
- debian 下实现LAMP 搭建服务器
- table修改状态改变td内容
- SQL的四种连接-左外连接、右外连接、内连接、全连接
- git命令
- mongodb连数据拷贝 + 恢复
- 读取并可视化DICOM图像(VTK & OpenCV)
- 编译期异常和运行期异常的区别
- 致未来的女友
- Java数组(1)
- TensorFlow 数据读取模块调用过程(inception)
- 猴子哟吐槽APP
- Throwable的几个常见方法
- 知识点总结
- JavaEE入门知识积累