Register Two Point Sets 注册两个点集

文章目录

    • Register Two Point Sets 注册两个点集
    • Visualize Gradient Descent 可视化梯度下降
    • Hyperparameter Search 超参数搜索
    • JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4类说明

原文url: https://examples.itk.org/src/registration/metricsv4/registertwopointsets/registertwopointsets

Register Two Point Sets 注册两个点集

与图像配准类似,可以对 n 维“移动”点集进行重新采样,以与“固定”点集对齐。可以使用 ITK 点集度量和 ITK 优化器来注册这两个集合。

在此示例中,我们创建两个具有任意偏移量的 itk.PointSet 表示,并选择参数以将它们与 TranslationTransform 对齐。我们使用 JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4 类来量化点集之间的差异,并使用 GradientDescentOptimizerv4 类通过修改变换参数来迭代减少这种差异。我们的示例还包括使用 matplotlib 和 itkwidgets 可视化参数表面的示例代码以及用于优化梯度下降性能的示例超参数搜索。

import os
import sys
import itertools
from math import pi, sin, cos, sqrtimport matplotlib.pyplot as plt
import numpy as npimport itk
from itkwidgets import view# 构造二个点集
# Generate two circles with a small offset
def make_circles(dimension: int = 2, offset: list = None):PointSetType = itk.PointSet[itk.F, dimension]RADIUS = 100if not offset or len(offset) != dimension:offset = [2.0] * dimensionfixed_points = PointSetType.New()moving_points = PointSetType.New()fixed_points.Initialize()moving_points.Initialize()count = 0step = 0.1for count in range(0, int(2 * pi / step) + 1):theta = count * stepfixed_point = list()fixed_point.append(RADIUS * cos(theta))for dim in range(1, dimension):fixed_point.append(RADIUS * sin(theta))fixed_points.SetPoint(count, fixed_point)moving_point = [fixed_point[dim] + offset[dim] for dim in range(0, dimension)]moving_points.SetPoint(count, moving_point)return fixed_points, moving_pointsPOINT_SET_OFFSET = [15.0, 15.0]
fixed_set, moving_set = make_circles(offset=POINT_SET_OFFSET)# Visualize point sets with matplotlibfig = plt.figure()
ax = plt.axes()n_points = fixed_set.GetNumberOfPoints()
ax.scatter([fixed_set.GetPoint(i)[0] for i in range(0, n_points)],[fixed_set.GetPoint(i)[1] for i in range(0, n_points)],
)
ax.scatter([moving_set.GetPoint(i)[0] for i in range(0, n_points)],[moving_set.GetPoint(i)[1] for i in range(0, n_points)],
)# 运行梯度下降优化
# 我们将使用 JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4 量化点集偏移,并在 10 次梯度下降迭代中最小化度量值。ExhaustiveOptimizerType = itk.ExhaustiveOptimizerv4[itk.D]
dim = 2
# Define translation parameters to update iteratively
TransformType = itk.TranslationTransform[itk.D, dim]
transform = TransformType.New()
transform.SetIdentity()PointSetType = type(fixed_set)
# Define a metric to reflect the difference between point sets
PointSetMetricType = itk.JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4[PointSetType]
metric = PointSetMetricType.New(FixedPointSet=fixed_set,MovingPointSet=moving_set,MovingTransform=transform,PointSetSigma=5.0,KernelSigma=10.0,UseAnisotropicCovariances=False,CovarianceKNeighborhood=5,EvaluationKNeighborhood=10,Alpha=1.1,
)
metric.Initialize()
# Define an estimator to help determine step sizes along each transform parameter2
ShiftScalesType = itk.RegistrationParameterScalesFromPhysicalShift[PointSetMetricType]
shift_scale_estimator = ShiftScalesType.New(Metric=metric, VirtualDomainPointSet=metric.GetVirtualTransformedPointSet(), TransformForward=True
)max_iterations = 10
# Define the gradient descent optimzer
OptimizerType = itk.GradientDescentOptimizerv4Template[itk.D]
optimizer = OptimizerType.New(Metric=metric,NumberOfIterations=max_iterations,ScalesEstimator=shift_scale_estimator,MaximumStepSizeInPhysicalUnits=8.0,MinimumConvergenceValue=-1,DoEstimateLearningRateAtEachIteration=False,DoEstimateLearningRateOnce=True,ReturnBestParametersAndValue=True,
)
iteration_data = dict()# Track gradient descent iterations with observers
def print_iteration():print(f"It: {optimizer.GetCurrentIteration()}"f" metric value: {optimizer.GetCurrentMetricValue():.6f} "# f' transform position: {list(optimizer.GetCurrentPosition())}'f" learning rate: {optimizer.GetLearningRate()}")def log_iteration():iteration_data[optimizer.GetCurrentIteration() + 1] = list(optimizer.GetCurrentPosition())optimizer.AddObserver(itk.AnyEvent(), print_iteration)
optimizer.AddObserver(itk.IterationEvent(), log_iteration)# Set first value to default transform position
iteration_data[0] = list(optimizer.GetCurrentPosition())
# Run optimization and print out results
optimizer.StartOptimization()print(f"Number of iterations: {optimizer.GetCurrentIteration() - 1}")
print(f"Moving-source final value: {optimizer.GetCurrentMetricValue()}")
print(f"Moving-source final position: {list(optimizer.GetCurrentPosition())}")
print(f"Optimizer scales: {list(optimizer.GetScales())}")
print(f"Optimizer learning rate: {optimizer.GetLearningRate()}")
print(f"Stop reason: {optimizer.GetStopConditionDescription()}")# Resample Moving Point Set 重采样移动点集
moving_inverse = metric.GetMovingTransform().GetInverseTransform()
fixed_inverse = metric.GetFixedTransform().GetInverseTransform()
transformed_fixed_set = PointSetType.New()
transformed_moving_set = PointSetType.New()for n in range(0, metric.GetNumberOfComponents()):transformed_moving_point = moving_inverse.TransformPoint(moving_set.GetPoint(n))transformed_moving_set.SetPoint(n, transformed_moving_point)transformed_fixed_point = fixed_inverse.TransformPoint(fixed_set.GetPoint(n))transformed_fixed_set.SetPoint(n, transformed_fixed_point)# Compare fixed point set with resampled moving point set to see alignment
fig = plt.figure()
ax = plt.axes()n_points = fixed_set.GetNumberOfPoints()
ax.scatter([fixed_set.GetPoint(i)[0] for i in range(0, n_points)],[fixed_set.GetPoint(i)[1] for i in range(0, n_points)],
)
ax.scatter([transformed_moving_set.GetPoint(i)[0] for i in range(0, n_points)],[transformed_moving_set.GetPoint(i)[1] for i in range(0, n_points)],
)

使用 matplotlib 可视化点集:
在这里插入图片描述

将固定点集与重采样移动点集进行比较以查看对齐情况:
在这里插入图片描述

Visualize Gradient Descent 可视化梯度下降

我们可以使用 ITK ExhaustiveOptimizerv4 类来查看优化器如何沿着变换参数和度量定义的表面移动。

# Set up the new optimizer# Create a new transform and metric for analysis
transform = TransformType.New()
transform.SetIdentity()metric = PointSetMetricType.New(FixedPointSet=fixed_set,MovingPointSet=moving_set,MovingTransform=transform,PointSetSigma=5,KernelSigma=10.0,UseAnisotropicCovariances=False,CovarianceKNeighborhood=5,EvaluationKNeighborhood=10,Alpha=1.1,
)
metric.Initialize()# Create a new observer to map out the parameter surface
optimizer.RemoveAllObservers()
optimizer = ExhaustiveOptimizerType.New(Metric=metric)# Use observers to collect points on the surface
param_space = dict()def log_exhaustive_iteration():param_space[tuple(optimizer.GetCurrentPosition())] = optimizer.GetCurrentValue()optimizer.AddObserver(itk.IterationEvent(), log_exhaustive_iteration)# Collect a moderate number of steps along each transform parameter
step_count = 25
optimizer.SetNumberOfSteps([step_count, step_count])# Step a reasonable distance along each transform parameter
scales = optimizer.GetScales()
scales.SetSize(2)scale_size = 1.0
scales.SetElement(0, scale_size)
scales.SetElement(1, scale_size)optimizer.SetScales(scales)optimizer.StartOptimization()
print(f"MinimumMetricValue: {optimizer.GetMinimumMetricValue():.4f}\t"f"MaximumMetricValue: {optimizer.GetMaximumMetricValue():.4f}\n"f"MinimumMetricValuePosition: {list(optimizer.GetMinimumMetricValuePosition())}\t"f"MaximumMetricValuePosition: {list(optimizer.GetMaximumMetricValuePosition())}\n"f"StopConditionDescription: {optimizer.GetStopConditionDescription()}\t"
)# Reformat gradient descent data to overlay on the plot
descent_x_vals = [iteration_data[i][0] for i in range(0, len(iteration_data))]
descent_y_vals = [iteration_data[i][1] for i in range(0, len(iteration_data))]# Plot the surface, extrema, and gradient descent data in a matplotlib scatter plot
fig = plt.figure()
ax = plt.axes()ax.scatter([x for (x, y) in param_space.keys()],[y for (x, y) in param_space.keys()],c=list(param_space.values()),cmap="Greens",zorder=1,
)
ax.plot(optimizer.GetMinimumMetricValuePosition()[0], optimizer.GetMinimumMetricValuePosition()[1], "kv"
)
ax.plot(optimizer.GetMaximumMetricValuePosition()[0], optimizer.GetMaximumMetricValuePosition()[1], "w^"
)for i in range(0, len(iteration_data)):ax.plot(descent_x_vals[i : i + 2], descent_y_vals[i : i + 2], "rx-")
ax.plot(descent_x_vals[0], descent_y_vals[0], "ro")
ax.plot(descent_x_vals[len(iteration_data) - 1], descent_y_vals[len(iteration_data) - 1], "bo")

在 matplotlib 散点图中绘制表面、极值和梯度下降数据:
在这里插入图片描述

我们还可以使用 itkwidgets 查看表面并将其导出为图像.

x_vals = list(set(x for (x, y) in param_space.keys()))
y_vals = list(set(y for (x, y) in param_space.keys()))x_vals.sort()
y_vals.sort(reverse=True)
array = np.array([[param_space[(x, y)] for x in x_vals] for y in y_vals])image_view = itk.GetImageViewFromArray(array)view(image_view)

Hyperparameter Search 超参数搜索

为了找到具有不同变换、度量和优化器的适当结果,通常需要比较超参数变化的结果。在此示例中,需要评估 JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4.PointSetSigma 参数和 GradientDescentOptimizerv4.DoEstimateLearningRate 参数的不同值的性能。梯度下降迭代数据沿二维散点图绘制,以比较并选择产生最佳性能的超参数组合。

# Index values for gradient descent logging
FINAL_OPT_INDEX = 0
DESCENT_DATA_INDEX = 1hyper_data = dict()
final_optimizers = dict()# sigma must be sufficiently large to avoid negative entropy results
point_set_sigmas = (1.0, 2.5, 5.0, 10.0, 20.0, 50.0)# Compare performance with repeated or one-time learning rate estimation
estimate_rates = [(False, False), (False, True), (True, False)]# Run gradient descent optimization for each combination of hyperparameters
for trial_values in itertools.product(point_set_sigmas, estimate_rates):hyper_data[trial_values] = dict()(point_set_sigma, est_rate) = trial_valuesfixed_set, moving_set = make_circles(offset=POINT_SET_OFFSET)transform = TransformType.New()transform.SetIdentity()metric = PointSetMetricType.New(FixedPointSet=fixed_set,MovingPointSet=moving_set,PointSetSigma=point_set_sigma,KernelSigma=10.0,UseAnisotropicCovariances=False,CovarianceKNeighborhood=5,EvaluationKNeighborhood=10,MovingTransform=transform,Alpha=1.1,)shift_scale_estimator = ShiftScalesType.New(Metric=metric, VirtualDomainPointSet=metric.GetVirtualTransformedPointSet())metric.Initialize()optimizer = OptimizerType.New(Metric=metric,NumberOfIterations=100,MaximumStepSizeInPhysicalUnits=3.0,MinimumConvergenceValue=-1,DoEstimateLearningRateOnce=est_rate[0],DoEstimateLearningRateAtEachIteration=est_rate[1],LearningRate=1e6,  # Ignored if either est_rate argument is TrueReturnBestParametersAndValue=False,)optimizer.SetScalesEstimator(shift_scale_estimator)def log_hyper_iteration_data():hyper_data[trial_values][optimizer.GetCurrentIteration()] = round(optimizer.GetCurrentMetricValue(), 8)optimizer.AddObserver(itk.IterationEvent(), log_hyper_iteration_data)optimizer.StartOptimization()final_optimizers[trial_values] = optimizer# Print results for each set of hyperparameters
print("PS_sigma\test once/each:\tfinal index\tfinal metric")
for trial_values in itertools.product(point_set_sigmas, estimate_rates):print(f"{trial_values[0]}\t\t{trial_values[1]}:\t\t"f"{final_optimizers[trial_values].GetCurrentIteration()}\t"f"{final_optimizers[trial_values].GetCurrentMetricValue():10.8f}")

我们可以使用 matplotlib 子图和条形图来比较每组超参数的梯度下降性能和最终度量值。在这个例子中,我们看到,一次估计学习率通常会随着时间的推移带来最佳性能,而每次迭代都估计学习率可能会阻止梯度下降有效收敛。提供最佳和最一致度量值的超参数集是 PointSetSigma=5.0 和 DoEstimateLearningRateOnce=True,这是我们在本笔记本中使用的值。

# Visualize metric over gradient descent iterations as matplotlib subplots.f, axn = plt.subplots(len(point_set_sigmas), len(estimate_rates), sharex=True)for (i, j) in [(i, j) for i in range(0, len(point_set_sigmas)) for j in range(0, len(estimate_rates))]:axn[i, j].scatter(x=list(hyper_data[point_set_sigmas[i], estimate_rates[j]].keys())[1:],y=list(hyper_data[point_set_sigmas[i], estimate_rates[j]].values())[1:],)axn[i, j].set_title(f"sigma={point_set_sigmas[i]},est={estimate_rates[j]}")axn[i, j].set_ylim(-0.08, 0)plt.subplots_adjust(top=5, bottom=1, right=5)
plt.show()# Compare final metric magnitudes
fig = plt.figure()
ax = fig.gca()labels = [f'{round(sig,0)}{"T" if est0 else "F"}{"T" if est1 else "F"}'for (sig, (est0, est1)) in itertools.product(point_set_sigmas, estimate_rates)
]vals = [final_optimizers[trial_values].GetCurrentMetricValue()for trial_values in itertools.product(point_set_sigmas, estimate_rates)
]ax.bar(labels, vals)
plt.show()

将梯度下降迭代中的度量可视化为 matplotlib 子图:
在这里插入图片描述

比较最终的度量值:

在这里插入图片描述

JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4类说明

url : https://itk.org/Doxygen/html/classitk_1_1JensenHavrdaCharvatTsallisPointSetToPointSetMetricv4.html

Jensen Havrda Charvat Tsallis 点集度量的实现。

给定指定的变换和方向,此类使用 Havrda-Charvat-Tsallis 熵族(众所周知的香农熵的泛化)和 Jensen 散度计算“固定”和“移动”点集对之间的值和导数。另一种看待信息理论度量族的方式是,这些点用于构建相应的可能密度函数。

此外,我们允许用户调用数据的流形 parzen 窗口。我们实际上可以计算每个点的协方差矩阵,以反映定位点集结构,而不是将各向同性高斯与每个点相关联。

为了加快度量计算速度,我们使用 ITK 的 K-d 树仅查询给定邻域的度量值。考虑到可能只需要一小部分点就可以很好地近似单个点的度量值,这可能是有道理的。所以我们要做的是转换每个点(使用指定的变换)并从转换后的点构建 k-d 树。

由 Nicholas J. Tustison、James C. Gee 在 Insight Journal 论文中贡献:https://www.insight-journal.org/browse/publication/317

注意
Tustison 等人在 2011 年报告的原始工作可选地采用了正则化项来防止移动点集合并到单个点位置。然而,在配准框架内,该术语的实用性有限,因为这种正则化由变换和任何显式正则化项决定。还请注意,已发表的工作适用于多个点集,每个点集都可以被视为“移动”,但这也不适用于此特定实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AI驱动TDSQL-C Serverless数据库技术实战】 AI电商数据分析系统——探索Text2SQL下AI驱动代码进行实际业务

目录 一、Text2SQL简介二、基于TDSQL-C Serverless的Text2SQL实战2.1、程序流程图2.2、实践流程2.2.1、配置TDSQL-C2.2.2、部署LLAMA模型2.2.3、本地依赖安装2.2.4、应用构建 2.3、运行效果 三、Text2SQL下的AI驱动 Text2SQL 是一种将自然语言查询转换为 SQL 查询的技术&#x…

中航资本:沪市主板代码以几开头?各板块开头代码是多少

各板块开始代码: 场内商场: 1、沪市主板:股票代码以600、601、603、605开始。 60开始的股票都是在上海证券交易所上市的股票。 600开始是上海证券交易所上市的一般股票,601开始的股票是主板股票,一般是大盘股蓝筹股…

Hi.Events —— 您的全方位活动管理与票务平台

大家好!今天给大家介绍一个超厉害的开源项目:Hi.Events,这是一个功能丰富的自托管活动管理和票务平台,无论是会议还是俱乐部活动,它都能帮你轻松搞定! 项目介绍 Hi.Events是一款功能丰富、自托管的开源活动…

Service和Endpoints

在 Kubernetes 中,Service 和 Endpoints 是两个非常重要的资源对象,它们共同用于定义和管理集群内部的服务发现和网络通信。下面详细介绍这两个资源对象的功能及其相互关系。 Service Service 是 Kubernetes 中用于定义抽象逻辑服务的资源对象。它提供…

学习Webpack中图片-JS-Vue-plugin

目录 图片文件资源模块类型 JS文件babel命令行使用babel-loaderbabel-preset Vue文件vue-loadervue/compiler-sfc pluginCleanWebpackPluginHtmlWebpackPluginDefinePlugin 图片文件 需要先在项目中使用图片,比较常见的使用图片的方式是两种: img元素&…

React Native中如何调用iOS的Face ID和Android的生物识别,react-native-biometrics

在React Native中调用Android和iOS的Face ID(iOS特有)或类似的功能(如Android上的生物识别,通常是通过指纹或面部识别),你需要分别处理两个平台,因为这两个操作系统提供的API和框架不同。 对于…

Linux【基础指令汇总】

目录 Linux命令的特点 1、文件管理 ls命令 cp命令 mkdir命令 mv命令 pwd命令 2、文档编辑 cat命令 echo命令 rm命令 tail命令 rmdir命令 3、系统管理 rpm命令 find命令 startx命令 uname命令 vmstat命令 4、磁盘管理 df命令 fdisk命令 lsblk命令 hdpar…

C语言_回调函数和qsort

1. 回调函数 回调函数就是一个通过函数指针调用的函数。 通俗易懂些讲就是把函数的指针作为参数传递给另一个函数,当在另一个函数中通过这个指针调用其所指向的函数时,那这个通过指针被调用的函数就叫做回调函数。 先上一个模拟计算机的代码&#xff…

Docker安装mysql8并配置主从复制

1. 安装mysql8 1.1 新增挂载文件 # 新增mysql挂载文件夹 mkdir -p /root/docker/mysql/m01/log mkdir -p /root/docker/mysql/m01/data mkdir -p /root/docker/mysql/m01/conf1.2 新增mysql配置文件 # 新增mysql配置文件 cd /root/docker/mysql/m01/conf vim my.cnf # 下面是…

关于git分支冲突问题

什么是冲突 在Git中,冲突是指两个或多个开发者对同一文件统一部份进行了不同的修改,并且在合并这些修改时,Git无法自动确定应该采用哪种修改而产生的情况。 分支冲突 如何出现并解决 在一个版本时,有一个master分支&#xff0c…

如何使用WinRAR锁定压缩文件,防止文件被修改或删除?

在日常工作中,我们经常需要分享压缩文件,但也可能面临文件被修改或删除的风险。想要保护压缩文件的完整性,不妨使用WinRAR提供的“锁定压缩文件”功能。这个功能可以防止文件被意外更改或删除,确保压缩文件保持原样。下面一起来看…

Linux中的 `vi` 与 `vim` 使用详解

文章目录 Linux中的 vi 与 vim 使用详解1. vi 编辑器1.1 什么是 vi1.2 vi 的基本用法1.2.1 启动 vi1.2.2 模式1.2.3 基本操作1.2.4 常用命令 1.3 vi 的特点 2. vim 编辑器2.1 什么是 vim2.2 vim 的基本用法2.2.1 启动 vim2.2.2 模式2.2.3 vim 的增强功能2.2.4 vim 的基本操作 2…

如何选择合适的量化交易策略,回测与模拟交易的实战演练

炒股自动化:申请官方API接口,散户也可以 python炒股自动化(0),申请券商API接口 python炒股自动化(1),量化交易接口区别 Python炒股自动化(2):获取…

解决跨域问题的案列

JSONP&#xff08;JSON with Padding&#xff09; JSONP 是一种通过 <script> 标签的跨域请求方法&#xff0c;它依赖于服务器支持并返回特定格式的响应。 示例&#xff1a; 前端&#xff1a; <script> function jsonpCallback(data) {console.log(Received data:…

websocket初识

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在 WebSocket API 中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两者之间就直接可以创建持久性…

【Android 14源码分析】Activity启动流程-1

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

Llama 3.2:利用开放、可定制的模型实现边缘人工智能和视觉革命

在我们发布 Llama 3.1 模型群后的两个月内&#xff0c;包括 405B - 第一个开放的前沿级人工智能模型在内&#xff0c;它们所产生的影响令我们兴奋不已。 虽然这些模型非常强大&#xff0c;但我们也认识到&#xff0c;使用它们进行构建需要大量的计算资源和专业知识。 我们也听到…

Meta首款多模态Llama 3.2开源:支持图像推理,还有可在手机上运行的版本 | LeetTalk Daily...

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 Meta最近推出的Llama Stack的发布标志着一个重要的里程碑。这一新技术的推出不仅为开发者提供了强大的多模态能力&#xff0c;还为企业和初…

编程题 7-15 计算圆周率【PAT】

文章目录 题目输入格式输出格式输入样例输出样例 题解解题思路完整代码 编程练习题目集目录 题目 根据下面关系式&#xff0c;求圆周率的值&#xff0c;直到最后一项的值小于给定阈值。 2 π 1 1 3 2 ! 3 5 3 ! 3 5 7 ​ n ! ​ 3 5 7 ⋯ ( 2 n 1 ) ⋯ {\frac 2…

安卓13设置删除网络和互联网选项 android13隐藏设置删除网络和互联网选项

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改4.1修改方法14.2修改方法25.编译6.彩蛋1.前言 有些客户不想让用户修改默认的网络配置,禁止用户进入里面调整网络相关的配置。 2.问题分析 像这个问题,我们有好几种方法去处理,这种需求一般…