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

server/2024/9/21 1:16:45/

薄板样条插值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/server/12146.html

相关文章

Hive数据类型

1.基本数据类型 示例: -- 创建表并定义列的数据类型 CREATE TABLE data_types_example (tinyint_column TINYINT,smallint_column SMALLINT,int_column INT,bigint_column BIGINT,boolean_column BOOLEAN,float_column FLOAT,double_column DOUBLE,string_column S…

最详细步骤解决:Apps targeting Android12 and higher are required to specify...

问题原因: 当targetSdkVersion>31时,需要在AndroidManifest.xml中配置android:exported的值,该值为boolean类型。 android:exported解释: activity 是否可由其他应用的组件启动: 如果设为 "true"&#…

人脸服务的算法内容

人脸算法可以返回在图像中找到的任何人脸的矩形坐标,以及与这些人脸相关的一系列属性,例如: 配饰:指示给定的人脸是否有配饰。 此属性会返回可能的配饰,包括头饰、眼镜和口罩,每个配饰的置信度分数介于 0 …

openGauss学习笔记-269 openGauss性能调优-TPCC性能调优测试指导-数据库服务端及客户端绑核

文章目录 openGauss学习笔记-269 openGauss性能调优-TPCC性能调优测试指导-数据库服务端及客户端绑核269.1 安装openGauss数据库269.2 停止数据库269.3 使用gs_guc工具修改数据库端口、IP等269.4 使用gs_guc工具设置如下参数269.5 执行如下命令以绑核方式启动服务端数据库269.6…

使用Pycharm运行spark实例时没有pyspark包(ModuleNotFoundError: No module named ‘py4j‘)

一、问题描述 在安装并配置pyspark,下载并打开Pycharm(专业版)后进行spark实例操作(笔者以统计文件中的行数为例)时,运行程序后提示ModuleNotFoundError: No module named py4j: 二、解决办法 …

Docker搭建启动gitbook

基本就是参考下面的文档即可。 Docker 安装 Gitbook 文档 启动的时候,会报错: Error: ENOENT: no such file or directory, stat ‘C:***demo_book\_book\gitbook\gitbook-plugin-fontsettings\fontsettings.js’ 解决方案: 用户目录下找…

【Flask】Flask中HTTP请求与接收

一、接收http请求与返回响应 在Flask中,可以通过app.route装饰器来定义路由函数。 app.route(/BringGoods,methods [POST, GET]) GET请求:使用request.args.get(key)或者request.values.get(key)来获取URL中的参数。 POST请求: 使用req…

单片机学习过程

继电器光耦隔离电压转换步进电机直流电机 arduino是最好用的一种,他提供了完整的设备库文件,任何外部设备只要查找相应的库,就可以很方便的使用 , 但是如果不去学习51 或stm32 或 嵌入式玩玩还可以,如果碰到没有实现的…