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.xdnf.cn/news/149837.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024/9/24有关1x1卷积核

深度学习笔记(六):1x1卷积核的作用归纳和实例分析_1x1卷积降维-CSDN博客 从这篇文章写的很好,主要讲的就是1x1卷积核有降维作用,还有就是线性映射作用(一般步进长度设置为的为1,也相当于是全连…

R包:ggspatial空间画图

ggplot2语法的空间图形画图 Spatial data plus the power of the ggplot2 framework means easier mapping. 加载R包 # install.packages("ggspatial")library(ggplot2) library(ggspatial) load_longlake_data()Using layer_spatial() and annotation_spatial() g…

Sql Developer期显示格式设置

默认时间格式显示 设置时间格式:工具->首选项->数据库->NLS->日期格式: DD-MON-RR 修改为: YYYY-MM-DD HH24:MI:SS 设置完格式显示:

数学家发现一种新空间镶嵌形状

不知道你没有读过空间嵌合的相关理论。嵌合或者平铺在欧拉的时代就被研究透了,被认为是低矮的树木上已经没有果子。不过最近发现了一种新的镶嵌结构。 数学家这样描述了这种新的形状,这种形状在自然界中很常见ーー从鹦鹉螺标志性的螺旋壳的腔室&#xf…

百度C++一面-面经总结

1、你知道网络编程服务端建立连接的流程吗?把用到的api说出来? server: 1.socket() int sockfd socket(AF_INET, SOCK_STREAM, 0);2.bind() struct sockaddr_in serv_addr; serv_addr.sin_family AF_INET; serv_addr.sin_addr.s_addr I…

C语言初识(一)

目录 前言 一、什么是C语言? 二、第一个C语言程序 (1)创建新项目 (2)编写代码 (3)main函数 三、数据类型 四、变量、常量 (1)变量的命名 (2&#x…

003_动手实现MLP(详细版)

常见的激活的有:RELU,sigmoid,tanh代码 import torch import numpy as np import sys import d2lzh_pytorch as d2l import torchvision from torchvision import transforms # 1.数据预处理 mnist_train torchvision.datasets.FashionMNIST(root/Users/wPycharmP…

2024年9月24日历史上的今天大事件早读

1550年9月24日 明代戏剧家汤显祖出生 1852年9月24日 法国人吉法尔制造的用蒸汽机推进的飞船试飞成功 1884年9月24日 中国近代化学的先驱徐寿逝世 1905年9月24日 吴樾壮炸五大臣,身殉革命 1909年9月24日 京张铁路通车 1910年9月24日 剧作家曹禺诞生 1930年9月2…

java并发工具包JUC(Java Util Concurrent)

1. 什么是JUC 1.1 JUC简介 JUC(Java Util Concurrent)是Java中的一个并发工具包,提供了一系列用于多线程编程的类和接口,旨在简化并发编程并提高其效率和可维护性。JUC库包含了许多强大的工具和机制,用于线程管理、同…

【Python报错已解决】NameError: name ‘reload‘ is not defined

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

【JVM】JVM执行流程和内存区域划分

是什么 Java 虚拟机 JDK,Java 开发工具包JRE,Java 运行时环境JVM,Java 虚拟机 JVM 就是 Java 虚拟机,解释执行 Java 字节码 JVM 执行流程 编程语言可以分为: 编译型语言:先将高级语言转换成二进制的机器…

飞腾平台perf工具PMU事件集成指南

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力,聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域,包含了应用使能套件、软件仓库、软件支持、软件适…

linux信号| 学习信号三步走 | 学习信号需要打通哪些知识脉络?

前言: 本节内容主要讲解linux下信号的预备知识以及信号的概念, 信号部分我们将会分为几个阶段进行讲解:信号的概念, 信号的产生, 信号的保存。本节主要讲解信号 ps:本节内容适合学习了进程相关概念的友友们进行观看哦 目录 什么是…

大模型算法岗常见面试题100道(值得收藏)

大模型应该是目前当之无愧的最有影响力的AI技术,它正在革新各个行业,包括自然语言处理、机器翻译、内容创作和客户服务等等,正在成为未来商业环境的重要组成部分。 截至目前大模型已经超过200个,在大模型纵横的时代,不…

测试从业者需要了解心理学和经济学

对于测试从业者来说,测试工作是一项技术活,但同时它也涉及到经济学和人类心理学一些重要因素。 在理想情况下,我们会测试程序的所有可能执行情况,而在大多数情况下,这几乎是不可能的。即使一个看起来非常简单的程序&a…

828华为云征文|使用华为云Flexus云服务器X搭建部署茶叶商城小程序uniapp

在当今数字化时代,小程序以其便捷、高效的特点成为了众多商家拓展业务的重要渠道。 本文将详细介绍如何使用新购买的华为云 Flexus 云服务器 X 搭建,一个带商品采集功能、H5积分商城、集合拼团、砍价、秒杀、会员、分销等等功能一个茶叶商城小程序。 后端…

共享wifi公司哪家正规合法?具体流程全公开!

随着共享经济时代的到来,以共享wifi为代表的多个项目逐渐成为众多创业赛道中的一大热门,推出共享wifi及其他项目的公司数量也因此呈现出了快速增长的态势。而这也让共享wifi等市场出现了鱼龙混杂的情况,连带着共享wifi哪家公司正规合法等相关…

写作高质量文案很难,文案自动生成器轻松解决

在当今信息爆炸的网络环境中,拥有一篇高质量的文案对于吸引受众、传达信息和实现目标至关重要。然而,写作高质量文案并非易事,它需要作者具备深厚的语言功底、创新的思维以及对目标受众的精准把握。这一系列的要求常常让许多人陷入写作的困境…

Windows电脑使用VNC远程桌面本地局域网内无公网IP树莓派5

目录 前言 1. 使用 Raspberry Pi Imager 安装 Raspberry Pi OS 2. Windows安装VNC远程树莓派 3. 使用VNC Viewer公网远程访问树莓派 3.1 安装Cpolar步骤 3.2 配置固定的公网地址 3.3 VNC远程连接测试 4. 固定远程连接公网地址 4.1 固定TCP地址测试 作者简介&#xff1…

drools规则引擎

1 单个文件 这个大多搜索导的都是把规则放到一个文件&#xff0c;这个是基础&#xff0c;但是实际应用就不太方便。如果你使用的jdk1.8&#xff0c;那么对应的drools版本为7.x 1.1 pom依赖 <drools.version>7.74.1.Final</drools.version> <dependency>&…