薄板样条插值TPS原理以及torch和opencv实现

devtools/2024/9/21 1:16:58/

薄板样条插值TPS原理以及torch和opencv实现

TPS_1">1、薄板样条插值TPS原理

概述

薄板样条(Thin Plate Spline),简称TPS,是一种插值方法,可找到通过所有给定点的“最小弯曲”光滑曲面。因为它一般都是基于2D插值,所以经常用在在图像配准中,也可以用于图像扭曲变形(扩充图像)。在两张图像中找出N个匹配点,应用TPS可以将这N个点形变到对应位置,同时给出了整个空间的形变(插值)。
在使用TPS图像配准过程中,需要输入原始图像初始点(也就是变换前像素点的位置),和目标图像的目标点(也就是变换之后像素点在目标图像中的位置)。通常为两张图像上的m组匹配点,如P1(x1,y1)->P1’(x1’,y1’)、P2(x2,y2)->P2’(x2’,y2’)…Pm(xm,ym)->Pm’(xm’,ym’)。可以通过Shift、Surf、Orb,以及光流跟踪等算法获取匹配点对。我们以文字扭曲变形为例,TPS算法就是将原始图像中的红色点,变换到目标图像中绿色点的过程,在这个过程中要求图像平面所在薄板弯曲变形所需的能量最小,能量公式如图1。
在这里插入图片描述

原理以及公式推导

在这里插入图片描述
图1
TPS形变的目标是求解一个函数f,使得f(Pi)=Pi’ (1≤i≤n),并且弯曲能量函数最小,同时图像上的其它点也可以通过插值函数f得到很好的校正。
可以证明薄板样条的插值函数就是弯曲能量最小的函数:
在这里插入图片描述
f(x,y) = [[xi’],
[yi’]]
在这里插入图片描述
因此
在这里插入图片描述
在这里插入图片描述
则公式中的前半部分可以表示成以下形式:
Pn×3 A3×2=
后半部分中的U可以表示成以下形式:
在这里插入图片描述
首先看基础函数在这里插入图片描述
的图像。
在这里插入图片描述
得到矩阵K
在这里插入图片描述
用K和P矩阵组合成L矩阵
在这里插入图片描述
令Y等于以下格式
在这里插入图片描述
则得
在这里插入图片描述
公式1
由上式得:
在这里插入图片描述
进而得到两个分解表达,第一个向量v表示的是目标点位置,向量o表示的是额外约束。
在这里插入图片描述
在上述表达式中,需要求解W和A矩阵,由公式1解得W和A矩阵:

在这里插入图片描述
到此,推到完毕。

2、torch实现

步骤解析:

  1. 先根据m个控制点求出w和a
    1.1. 构造P、K、Y矩阵
    1.2. 计算W、A
    1.3. 生成网格grid,并计算K,P
    1.4. 计算输出结果Y
  2. 然后可以根据输入点p得到目标点p’。
    p’ = p@a+k@w
    其中@表示点乘p的维度为m×3、a的3×2、k的m×m、w的m×2
  3. 在计算w和a的过程,m的值为控制点的数量。
  4. 在推理阶段,m的值为所有的像素点的数量n(n=H*W)。
python">import cv2
import numpy as np
import random
import torch
from torchvision.transforms import ToTensor, ToPILImage
DEVICE = torch.device("cpu")
def choice3(img):'''产生波浪型文字:param img::return:'''h, w = img.shape[0:2]N = 5pad_pix = 50points = []dx = int(w/ (N - 1))for i in range( N):points.append((dx * i,  pad_pix))points.append((dx * i, pad_pix + h))#加边框img = cv2.copyMakeBorder(img, pad_pix, pad_pix, 0, 0, cv2.BORDER_CONSTANT,value=(int(img[0][0][0]), int(img[0][0][1]), int(img[0][0][2])))#原点source = np.array(points, np.int32)source = source.reshape(1, -1, 2)#随机扰动幅度rand_num_pos = random.uniform(20, 30)rand_num_neg = -1 * rand_num_posnewpoints = []for i in range(N

http://www.ppmy.cn/devtools/12320.html

相关文章

学习配置文件

1.yml的语法格式问题: 2.配置文件获取数据: Value方式: Environment: 获取自定义对象的方式: 设置get和set方法,还有toString方法。 3. 日志配置: logo的配置: 日志插件&#xff…

Microsoft Edge:探索你可能未充分利用的8个实用功能

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

基于RT-Thread的智能家居助手

一、项目简介 智能家居助手主要基于RT-Thread开发的,该系统主要分为语音子系统,环境监测子系统,智能控制子系统,智能网关子系统,音乐播放器,云端以及应用软件七大部分。语音子系统可通过语音进行人机交互来…

导出JVM的线程信息

1. 查询出Java应用的进程的PID ps -ef|grep java 此时的PID是 33 2. 使用JDK自带的工具jstack导出日志 jstack -l 33 > 2022jstack.log 3.然后直接下载

界面组件DevExpress Blazor UI v23.2 - 支持.NET 8、全新的项目模版

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生Blazor UI组件(包括Pivot Grid、调度程序、图表、数据编辑器和报表等)。 DevExpress Blazor控件目前已经升级…

Python自动化系列5

import selenium #工具里的所有的内容都导入 from selenium import webdriver #从selenium 工.具里导入webdriver库 import time #导入time这个模块— Python自带的 #选择chrome这个浏览器,初始化driver可以浏览器进行沟通建立会话 session driver webdriver.Ch…

Linux怎么安装czmq(物联网消息通讯轻量级消息队列)

首先打开yum源配置文件 ,加载czmq的官方源 [rootlocalhost package]# cd /etc/yum.repos.d/输入czmq的官方yum 源路径 [rootlocalhost yum.repos.d]# wget https://download.opensuse.org/repositories/network:messaging:zeromq:git-stable/CentOS_7/network:mes…

SpringCloudAlibaba之Sentinel简单使用

SpringCloudAlibaba之Sentinel简单使用 文章目录 SpringCloudAlibaba之Sentinel简单使用sentinel入门资源定义SphU(抛出异常方式)SphO(布尔类型方式)SentinelResource(注解的方式定义)SentinelResource使用前置条件使用SentinelResource定义资源定义blockHandler和fallback方法…