IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> win10+visual studio 2022+itk+生成drr -> 正文阅读

[开发工具]win10+visual studio 2022+itk+生成drr

前言

为了使用CT模拟照射生成drr(关于drr,默认大家已经知道),捣鼓了一阵itk,现在将有关内容记录一下,同时希望对其他同学有帮助。

1. 编译itk

1.1 准备工具

  • cmake,按照相关教程下载安装
  • visual studio 2022,按照相关教程下载安装
  • itk官网下载itk的压缩包
    在这里插入图片描述

1.2 准备3个文件夹

  • src,用来放置解压的itk源文件,解压下载的itk压缩包到这个文件夹中
  • bin,用来放置cmake的生成文件
  • release,用来放置visual studio 2022生成的最终可使用的文件

1.3 cmake的工作

  • 首先放置好文件夹路径,勾上对应旋转
    在这里插入图片描述
  • 然后点击: config \textbf{config} config
    在这里插入图片描述
  • 设置 vs2022 \textbf{vs2022} vs2022 x64 \textbf{x64} x64,点击完成
    在这里插入图片描述
    然后它自己会运行一会儿,等出现 C o n f i g u r i n g ? d o n e Configuring\ done Configuring?done的时候,会出现一大片红色区域,不用慌,且看下一步。
  • 修改cmke的 2 \textbf{2} 2个地方
    • 第1个地方是: 添加勾选BUILD_SHARED_LIBS,生成dll 在这里插入图片描述
    • 第2个地方是:在CMAKE下,修改CMAKE_INSTALL_PREFIX为之前建好的release文件夹
      在这里插入图片描述
      然后再点击 c o n f i g config config。它又会运行一段时间,然后等出现 C o n f i g u r i n g ? d o n e Configuring\ done Configuring?done的时候,就只有1个地方是红的了。
      在这里插入图片描述
      没关系,继续点 c o n f i g config config,不出意外,这次就没有红的了。
      综上所述,总共点了 3 3 3 c o n f i g config config
  • 点击 Generate \textbf{Generate} Generate,生成文件到 b i n bin bin文件夹
    在这里插入图片描述
    等出现 G e n e r a t i n g ? d o n e Generating\ done Generating?done的时候,点击 O p e n ? P r o j e c t Open\ Project Open?Project
    在这里插入图片描述
    这个时候会通过vs2022打开bin文件夹下的一个项目,加载需要一段时间,耐心等待。

1.4 visual studio 2022的工作

  • 第1步,选择 生成 ? 批生成 生成\longrightarrow批生成 生成?批生成
    在这里插入图片描述
  • 第2步,勾选ALL_BUILD,选择release,点击生成。这一步费时较长。
    在这里插入图片描述
    检查是否生成成功:
    在这里插入图片描述
  • 第3步,安装。
    同样也是通过 生成 ? 批生成 生成\longrightarrow批生成 生成?批生成,取消掉之前的ALL_BUILD的勾选,勾选INSTALL的release版本,点击生成。
    在这里插入图片描述
    等生成完毕之后,就会在之前建的 r e l e a s e release release文件夹下生成4个文件夹:
    在这里插入图片描述
    在这里插入图片描述
    其中,主要用到这个三个目录
    • bin文件夹:保存生成的dll,后面要配置到环境变量中
    • include: 包含目录
    • lib:库目录
      至此,第1部分,编译itk就做完了。

2. 使用编译完成的itk

为了测试我们生成的文件是否有效,应该搞一段代码来测试一下

2.1 配置bin目录的环境变量

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.2 重启电脑

这是为了使得配置的bin目录生效。

2.3 新建工程测试

新建一个空项目,添加一个cpp文件,把下面这段代码贴上去:

#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkResampleImageFilter.h>
#include <itkCenteredEuler3DTransform.h>
#include <itkNearestNeighborInterpolateImageFunction.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkRescaleIntensityImageFilter.h>
#include <itkGDCMImageIO.h>
#include <itkPNGImageIO.h>
#include <itkPNGImageIOFactory.h>
#include <itkGDCMSeriesFileNames.h>
#include <itkImageSeriesReader.h>
#include <itkImageSeriesWriter.h>
#include <itkNumericSeriesFileNames.h>
#include <itkGiplImageIOFactory.h>
#include <itkCastImageFilter.h>
#include <itkNIFTIImageIO.h>
#include <itkNIFTIImageIOFactory.h>
#include <itkMetaImageIOFactory.h>
#include <itkRayCastInterpolateImageFunction.h>
#include <iostream>
#include <io.h>

using namespace std;

int main() {
	// 你自己的CT文件的nii路径
	const string file_path = "E:/hip_data/images/001.nii.gz";
	
	const string out_drr = "drr/"; // 自己在当前项目下建一个drr的文件夹
	
	string save_path = out_drr + "dr4.png";
	cout << "input_path = " << file_path << endl;
	cout << "save_path = " << save_path << endl;

	bool ok;
	bool verbose = false;

	float rx = -90;
	float ry = 0;
	float rz = 0;

	float tx = 0;
	float ty = 0;
	float tz = 0;

	float cx = 0;
	float cy = 0;
	float cz = 0;

	float sid = 400;

	float sx = 1.5;
	float sy = 1.5;

	int dx = 512;
	int dy = 512;

	float o2Dx = 0;
	float o2Dy = 0;

	double threshold = -400;

	const unsigned int Dimension = 3;
	using InputPixelType = float;
	using OutputPixelType = unsigned char;
	using InputImageType = itk::Image<InputPixelType, Dimension>;
	using OutputImageType = itk::Image<OutputPixelType, Dimension>;

	InputImageType::Pointer image;
	
	using ReaderType = itk::ImageFileReader<InputImageType>;
	ReaderType::Pointer reader = ReaderType::New();
	itk::NiftiImageIOFactory::RegisterOneFactory();
	reader->SetFileName(file_path);
	try {
		reader->Update();
	}
	catch (itk::ExceptionObject& err) {
		cerr << "error exception object caught!" << endl;
		cerr << err.what() << endl;
		return EXIT_FAILURE;
	}
	image = reader->GetOutput();

	if (verbose) {
		const InputImageType::SpacingType spacing = image->GetSpacing();
		cout << endl << "Input: ";

		InputImageType::RegionType region = image->GetBufferedRegion();
		region.Print(cout);

		cout << " Resolution: [";
		for (int i = 0; i < Dimension; i++) {
			cout << spacing[i];
			if (i < Dimension - 1) cout << ", ";
		}
		cout << "]" << endl;

		const InputImageType::PointType origin = image->GetOrigin();
		cout << " Origin: [";
		for (int i = 0; i < Dimension; i++) {
			cout << origin[i];
			if (i < Dimension - 1) cout << ", ";
		}
		cout << "]" << endl << endl;
	}


	using FilterType = itk::ResampleImageFilter<InputImageType, InputImageType>;
	FilterType::Pointer filter = FilterType::New();
	filter->SetInput(image);
	filter->SetDefaultPixelValue(0);

	using TransformType = itk::CenteredEuler3DTransform<double>;
	TransformType::Pointer transform = TransformType::New();

	transform->SetComputeZYX(true);
	TransformType::OutputVectorType translation;

	translation[0] = tx;
	translation[1] = ty;
	translation[2] = tz;

	const double dtr = atan(1.0) * 4.0 / 180.0;

	transform->SetTranslation(translation);
	transform->SetRotation(dtr * rx, dtr * ry, dtr * rz);

	InputImageType::PointType imOrigin = image->GetOrigin();
	InputImageType::SpacingType imRes = image->GetSpacing();

	using InputImageRegionType = InputImageType::RegionType;
	using InputImageSizeType = InputImageRegionType::SizeType;

	InputImageRegionType imRegion = image->GetBufferedRegion();
	InputImageSizeType imSize = imRegion.GetSize();

	imOrigin[0] += imRes[0] * static_cast<double>(imSize[0]) / 2.0;
	imOrigin[1] += imRes[1] * static_cast<double>(imSize[1]) / 2.0;
	imOrigin[2] += imRes[2] * static_cast<double>(imSize[2]) / 2.0;
	
	TransformType::InputPointType center;
	center[0] = cx + imOrigin[0];
	center[1] = cy + imOrigin[1];
	center[2] = cz + imOrigin[2];
	transform->SetCenter(center);

	if (verbose) {
		cout << "Image size: " << imSize[0] << ", " << imSize[1] << ", " << imSize[2]
			<< endl << " resolution: " << imRes[0] << ", " << imRes[1] << ", " << imRes[2]
			<< endl << " origin: " << imOrigin[0] << ", " << imOrigin[1] << ", " <<
			imOrigin[2] << endl << " center: " << center[0] << ", " << center[1]
			<< ", " << center[2] << endl << "Transform: " << transform << endl;
	}
	using InterpolatorType = itk::RayCastInterpolateImageFunction<InputImageType, double>;
	InterpolatorType::Pointer interpolator = InterpolatorType::New();
	interpolator->SetTransform(transform);

	interpolator->SetThreshold(threshold);
	InterpolatorType::InputPointType focalpoint;

	focalpoint[0] = imOrigin[0];
	focalpoint[1] = imOrigin[1];
	focalpoint[2] = imOrigin[2] - sid / 2.0;

	interpolator->SetFocalPoint(focalpoint);

	if (verbose) {
		cout << "Focal Point: "
			<< focalpoint[0] << ", "
			<< focalpoint[1] << ", "
			<< focalpoint[2] << endl;
	}
	interpolator->Print(std::cout);

	filter->SetInterpolator(interpolator);
	filter->SetTransform(transform);

	// setup the scene
	InputImageType::SizeType   size;
	size[0] = dx;  // number of pixels along X of the 2D DRR image
	size[1] = dy;  // number of pixels along Y of the 2D DRR image
	size[2] = 1;   // only one slice

	filter->SetSize(size);

	InputImageType::SpacingType spacing;

	spacing[0] = sx;  // pixel spacing along X of the 2D DRR image [mm]
	spacing[1] = sy;  // pixel spacing along Y of the 2D DRR image [mm]
	spacing[2] = 1.0; // slice thickness of the 2D DRR image [mm]
	filter->SetOutputSpacing(spacing);

	if (verbose)
	{
		std::cout << "Output image size: "
			<< size[0] << ", "
			<< size[1] << ", "
			<< size[2] << std::endl;

		std::cout << "Output image spacing: "
			<< spacing[0] << ", "
			<< spacing[1] << ", "
			<< spacing[2] << std::endl;
	}

	double origin[Dimension];
	origin[0] = imOrigin[0] + o2Dx - sx * ((double)dx - 1.) / 2.;
	origin[1] = imOrigin[1] + o2Dy - sy * ((double)dy - 1.) / 2.;
	origin[2] = imOrigin[2] + sid / 2.;
	filter->SetOutputOrigin(origin);
	if (verbose)
	{
		std::cout << "Output image origin: "
			<< origin[0] << ", "
			<< origin[1] << ", "
			<< origin[2] << std::endl;
	}

	// create writer
	using RescaleFilterType = itk::RescaleIntensityImageFilter<InputImageType, OutputImageType>;
	RescaleFilterType::Pointer rescaler = RescaleFilterType::New();
	rescaler->SetOutputMinimum(0);
	rescaler->SetOutputMaximum(255);
	rescaler->SetInput(filter->GetOutput());

	using WriterType = itk::ImageFileWriter<OutputImageType>;
	WriterType::Pointer writer = WriterType::New();

	using pngType = itk::PNGImageIO;
	pngType::Pointer pngIO1 = pngType::New();
	itk::PNGImageIOFactory::RegisterOneFactory();
	writer->SetFileName(save_path);
	writer->SetImageIO(pngIO1);
	writer->SetImageIO(itk::PNGImageIO::New());
	writer->SetInput(rescaler->GetOutput());
	try
	{
		std::cout << "Writing image: " << save_path << std::endl;
		writer->Update();
	}
	catch (itk::ExceptionObject& err)
	{
		std::cerr << "ERROR: ExceptionObject caught !" << std::endl;
		std::cerr << err << std::endl;
	}


	return 0;
}

显然会报很多错误,因为我们还没有对项目进行配置。

  • 第1,构造属性表,选择属性管理器—>release|x64,右键,选择添加新的属性表
    在这里插入图片描述
    在这里插入图片描述
    随意命名一下吧,然后双击打开它。
  • 包含目录,添加 i n c l u d e include include文件夹
    在这里插入图片描述
    在这里插入图片描述
  • 库目录,选择 l i b lib lib文件夹
    在这里插入图片描述
  • lib文件添加。在链接器—>输入—>附加依赖项里面将 l i b lib lib文件夹下的所有后缀为 . l i b .lib .lib的文件全部添加进去。
    在这里插入图片描述
    在该文件夹下使用cmd命令行生成txt:
    在这里插入图片描述
    打开txt复制粘贴上去。点击确定
    在这里插入图片描述
    点击应用,确定
    在这里插入图片描述
  • 最后一步
    回来发现还是红的,最后将debug改成release就可以了。因为我们编译的是release版本。
    在这里插入图片描述
  • 在当前项目下新建drr文件夹,修改自己的ct数据路径,就可以调试运行了
    在这里插入图片描述

在这里插入图片描述
最后在drr文件夹中生成的drr图像
在这里插入图片描述

大功告成

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:48:33  更:2022-09-21 00:51:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 8:49:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码