详解LK光流法(含金字塔多层光流),反向光流法(附代码)

特征点匹配之-光流法(LK) 阅读详情
AI摘要

本文详细介绍了光流法如何通过最小二乘和高斯牛顿方法来估计特征点在连续图像之间的运动,涉及灰度不变假设、光流计算步骤、窗口像素处理和逆向光流的优化策略。通过实例演示了从提取特征点到计算光流的过程,以及多层金字塔光流的使用,以提高精度和抵抗局部极值问题。

LK光流法可用来跟踪特征点的位置。
比如在img1中的特征点,由于相机或物体的运动,在img2中来到了不同的位置。后面会称img1为Template(T),img2为I。

光流法有个假设:
灰度不变假设:同一个空间点的像素灰度值,在各图像中是不变的,也就是说T中特征点处的灰度,到了I中仍然是一样的灰度。

这就要求光照恒定,物体反射恒定,是个很强的假设。

现在要估计的是运动偏移量[dx, dy],也就是光流。仅用一个点无法解,一般会取一个窗口内的像素,考虑它们具有相同的运动。

用最小二乘法来解像素的运动如下:
在这里插入图片描述
这里的W表示对图像 I 进行像素变换,把它变到T所在的时间,即运动前的图像,看跟T有多大误差。这里假设对窗口内的像素进行变换。
p是运动位移量(dx, dy)。

这是个非线性优化问题,因为像素是跟坐标不是线性关系。
这时可以假设p已经知道了(假设就是运动前的点坐标,或者给定一个值),在它的基础上不断加上增量进行调整。
于是变成了优化如下问题,把它叫做error:
在这里插入图片描述
每次估计出增量 Δ p \Delta p Δp
更新p,
在这里插入图片描述
(4)(5)两步反复迭代直到达到收敛条件,收敛条件可以是
Δ p \Delta p Δp 小于一个阈值,或者(4)中的cost比前一次大(理论上cost是逐渐减小的)

上面就是最小二乘法求光流的大概步骤,具体如何求 Δ p \Delta p Δp,下面是高斯牛顿法解 Δ p \Delta p Δp,及迭代出光流(dx, dy)的步骤:

  1. 把上面的(4)式,也就是cost函数,对 I ( W ( x ; p + Δ p ) ) I(W(x;p+\Delta p)) I(W(x;p+Δp))进行一阶泰勒展开,得到:
    在这里插入图片描述
    这里的 ▽ I \bigtriangledown I ▽I指在图像 I,也就是img2中对特征点处求x,y方向上的梯度,然后通过W变换回T的坐标中。
    ∂ W / ∂ p \partial W/ \partial p ∂W/∂p指W对p求偏导。
    举个例子吧,假如W如下
    在这里插入图片描述
    那么 [ ∂ W x / ∂ p 1 ∂ W x / ∂ p 2 ∂ W y ∂ p 1 ∂ W y / ∂ p 2 ] = [ 1 0 0 1 ] \left[ \begin{matrix} \partial W_x/ \partial p1 & \partial W_x/ \partial p2 \\ \partial W_y \partial p1 & \partial W_y/ \partial p2 \\ \end{matrix} \right] = \left[ \begin{matrix} 1 &0 \\ 0 & 1 \\ \end{matrix} \right] [∂Wx​/∂p1∂Wy​∂p1​∂Wx​/∂p2∂Wy​/∂p2​]=[10​01​]
    上面的(p1, p2)就是我们要求的光流(dx, dy), 这个 ∂ W / ∂ p \partial W/ \partial p ∂W/∂p就是雅可比矩阵 J J J

  2. 上面(6)式对 Δ p \Delta p Δp求偏导,得到:
    在这里插入图片描述
    先解释一下 Δ p \Delta p Δp和上面p的关系,上面的p是我们要求的光流(dx, dy),而直接求比较困难,现在假设已经知道初始的(dx, dy), 比如(0, 0),要通过每次求(dx, dy)的增量( Δ d x , Δ d y ) \Delta dx, \Delta dy) Δdx,Δdy), 也就是 Δ p \Delta p Δp,来不断修正(dx, dy), 直到收敛。
    另上面(9)式偏导为0,可求得:
    在这里插入图片描述
    这就是最小二乘法的解,
    其实可以想到最小二乘法解增量问题的形式一般是
    H Δ x = b H \Delta x = b HΔx=b, 其中
    H = J J T , b = − J e H = JJ^{T}, b = -Je H=JJT,b=−Je, e e e即为error函数。

同样地,上面的 H = J J T H = JJ^{T} H=JJT,
在这里插入图片描述
Δ p \Delta p Δp一旦求出,就可以不断迭代,得到最终的光流(dx, dy), 也就是p了。

下面通过一个例子说明如何追踪特征点的光流。

先在img1,也就是T里提取特征点kp1

Mat img1 = imread("../imgs/LK1.png", 0); //T
Mat img2 = imread("../imgs/LK2.png", 0);  //I

//key points
vector<KeyPoint> kp1;
FAST(img1, kp1, 40); //可以用其他特征点

对每个特征点kp1[i], 设初始(dx, dy) = (0, 0)

auto kp = kp1[i];
double dx = 0, dy = 0;  //需要估计

要用到的几个矩阵

Eigen::Matrix2d H = Eigen::Matrix2d::Zero();  //Hessian
Eigen::Vector2d b = Eigen::Vector2d::Zero();  //bias
Eigen::Vector2d J;   //Jacobian

前面说了,不能只计算一个点,要计算一个小窗口内的点,并假设它们的运动是一样的。
代码中出现了逆向光流法,这个后面解释。
下面的代码中求出了H, b, 而 Δ p = H − 1 b \Delta p = H^{-1}b Δp=H−1b

//计算cost和jacobian
for(int x = -half_patch_size; x < half_patch_size; x++) {
    for(int y = -half_patch_size; y < half_patch_size; y++) {
        double error = GetPixelValue(img1, kp.pt.x + x, kp.pt.y + y) -
                GetPixelValue(img2, kp.pt.x + x + dx, kp.pt.y + y + dy);
        if(inverse == false) {
            //error分别对dx, dy求导,因为是离散的,所以用dx+1,dx-1的位移差,dy同样
            //x, y是窗口内的偏移量
            //img1中没有dx, dy的变量,所以只有img2
            J = -1.0 * Eigen::Vector2d(
                    0.5 * (GetPixelValue(img2, kp.pt.x + x + dx + 1, kp.pt.y + y + dy) -
                           GetPixelValue(img2, kp.pt.x + x + dx - 1, kp.pt.y + y + dy)),
                    0.5 * (GetPixelValue(img2, kp.pt.x + x + dx, kp.pt.y + y + dy + 1) -
                           GetPixelValue(img2, kp.pt.x + x + dx, kp.pt.y + y + dy - 1))
                    );
        }else if (iter == 0) {
            //反向光流法,只需计算第一次的H,后面H固定
            J = -1.0 * Eigen::Vector2d(
                    0.5 * (GetPixelValue(img1, kp.pt.x + x + 1, kp.pt.y + y) -
                              GetPixelValue(img1, kp.pt.x + x - 1, kp.pt.y + y)),
                    0.5 * (GetPixelValue(img1, kp.pt.x + x, kp.pt.y + y + 1) -
                              GetPixelValue(img1, kp.pt.x + x, kp.pt.y + y - 1))
                    );
        }

        //计算H, b and set cost
        b += -error * J;
        cost += error * error;
        //正向光流法每次迭代都要更新H
        if(inverse == false || iter == 0) {
            H += J * J.transpose();
        }
    }

Δ p = H − 1 b \Delta p = H^{-1}b Δp=H−1b

Eigen::Vector2d update = H.ldlt().solve(b);  //避免求矩阵的逆

//最小二乘收敛
if(iter > 0 && cost > lastCost) {
    break;
}

迭代更新(dx, dy)

dx += update[0];
dy += update[1];
lastCost = cost;

最后(dx, dy)就是我们要求的光流,根据img1中的keypoint kp1, 可以追踪到img2中的keypoint坐标为

kp2[i].pt = kp.pt + Point2f(dx, dy);

以上是单层光流,下面说说金字塔的多层光流
在这里插入图片描述假设左边最下面一层(3号)是原图像img1 (T), 那么往上(2号,1号)就是对img1的缩放,右边最下面一层是img2, 往上是对img2的缩放。

double pyramid_scale = 0.5;
//create pyramids
vector<Mat> pyr1, pyr2;  //image pyramids
for(int i = 0; i < pyramids; i++) {
    if(i == 0) {
        pyr1.push_back(img1);
        pyr2.push_back(img2);
    } else {
        Mat img1_pyr, img2_pyr;
        //cv::Size(列,行)
        resize(pyr1[i - 1], img1_pyr,
               Size(pyr1[i-1].cols * pyramid_scale, pyr1[i-1].rows * pyramid_scale));
        resize(pyr2[i - 1], img2_pyr,
                Size(pyr2[i-1].cols * pyramid_scale, pyr2[i-1].rows * pyramid_scale));
        pyr1.push_back(img1_pyr);
        pyr2.push_back(img2_pyr);
    }
}

计算光流时,从最上面一层(1号)计算。
左边1号缩放的img1为T,右边1号缩放的img2为I,以img1的keypoint kp1计算光流,得到kp2。
到计算下面两层的时候,以上一层光流的结果作为下一层的初始假设,而不是像最上层那样假设(dx, dy) = (0, 0)。

double dx = 0, dy = 0;  //需要估计
if(has_initial) {
    dx = kp2[i].pt.x - kp.pt.x;  //x位移
    dy = kp2[i].pt.y - kp.pt.y;  //y位移
}

这样做有什么好处呢?假设移动了20个像素,直接求光流可能由于变化太大而陷入局部极值;但是缩放之后可能就只移动了5个像素,这就是一种coarse to fine的思想。

现在来说逆向光流法,
前面正向光流每迭代一次都要计算一次H,计算量很大。考虑有没有一种方法可以只计算一次H,然后后面都用这个H。
逆向光流法是前面正向光流的逆向,也就是交换一下方向,现在是从I 反向回到T,也就是从运动之后的 I 变换回运动前的T。
引用一个图方便理解
在这里插入图片描述

error函数如下,只需要交换T 和 I
在这里插入图片描述
计算得到:
在这里插入图片描述
其中
在这里插入图片描述
可以看到由于T 是运动前的img,并没有移动p=(dx, dy),因此H和p无关,每次迭代计算 Δ p \Delta p Δp时H是恒定的,只需要在第一次迭代时计算一次即可。对应了上面代码的如下部分:

}else if (iter == 0) {
            //反向光流法,只需计算第一次的H,后面H固定
            //H只和T,也就是img1有关
            J = -1.0 * Eigen::Vector2d(
                    0.5 * (GetPixelValue(img1, kp.pt.x + x + 1, kp.pt.y + y) -
                              GetPixelValue(img1, kp.pt.x + x - 1, kp.pt.y + y)),
                    0.5 * (GetPixelValue(img1, kp.pt.x + x, kp.pt.y + y + 1) -
                              GetPixelValue(img1, kp.pt.x + x, kp.pt.y + y - 1))
                    );
        }

每次迭代中H不需再更新

if(inverse == false || iter == 0) {
    H += J * J.transpose();
}

上面就是正向光流,反向光流,如果想了解更加详细的资料,请参考paper
完整版代码请参考链接

光流法小结 1. 定义空间运动物体在观察成像平面上的像素运动的瞬时速度,是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。也就是说,由空间域到图像平面的投影。而通俗来讲,把图像中的每一个点的瞬时速度和方向找出来就是光流。2. 光流有什么用通过光流判断物体距离我们的远近。 一般而言,远景的物体相对来说光流较小,而近景物体 阅读详情

相关推荐

【机器视觉】运动分析——LK光流

光流(Optical Flow)是指图像中物体运动在二维图像平面上的投影,表现为图像亮度模式的表观运动。它描述了图像中每个像素点在连续帧之间的运动矢量。

weixin_73858308的博客 1524

一文理清LK光流

举出几种光流方法,说明LK光流的建模方式? 光流方法是用于估计图像序列中像素点运动的技术,广泛应用于计算机视觉和视频处理领域。以下是几种常见的光流方法: Lucas-Kanade (LK) 方法: 一种基于局部窗口的光流估计方法,假设在小的窗口内像素运动是一致的。 Horn-Schunck 方法: 一种全局方法,通过最小化整个图像的光流场的平滑性来估计运动,对于平滑和连续的运动场估计非常有效。 Farneback 方法: 这种方法基于多尺度的多项式展开来估计光流,能够提供比较稠密的光流

dc爱傲雪和技术 1680

从理论到实践:LK光流法、金字塔优化与反向光流实现全解析(附代码)

本文全面解析了LK光流法及其优化技术,包括金字塔多层光流和反向光流法的实现原理与代码实践。通过详细的数学推导和Python代码示例,帮助开发者掌握从基础光流计算到工业级应用的关键技术,提升计算机视觉项目中运动追踪的准确性和效率。

weixin_30325971的博客 475

【计算机视觉】基于光流特征的目标跟踪算法LK光流法的讲解(图文解释 超详细)

【计算机视觉】基于光流特征的目标跟踪算法LK光流法的讲解(图文解释 超详细)

showswoller的博客 3710

光流法和直接法介绍

光流为追踪源图像某个点在其他图像中的运动, 一般分为稀疏光流和稠密光流,其本质是估计像素在不同时刻图像中的运动本文主要介绍LK光流。

m0_37604894的博客 1903

LK光流法在无人机视觉避障中的实战:如何用金字塔光流稳定跟踪动态目标?

本文深入探讨了LK光流法在无人机视觉避障中的应用,重点介绍了金字塔光流技术在动态目标跟踪中的优化策略。通过分析多尺度运动特性和硬件限制,提供了金字塔光流的工程实现细节和反向光流法的实时性优化方案,帮助开发者在复杂环境中提升避障系统的响应速度和准确性。

weixin_30786657的博客 579

LK光流法与反向LK光流法

文章目录一、基本概念二、LK光流法1、空间点在图像中的灰度表示 一、基本概念 光流法:光流法是一种描述像素随时间在图像之间运动的方法 稀疏光流法:计算部分像素运动的称为稀疏光流法,以 Lucas-Kanade 光流为代表 稠密光流法:计算所有像素的称为稠密光流法,以 Hom-Schunck 光流为代表 灰度不变假设:同一个空间点的像素灰度值,在各个图像中是固定不变的。这是光流法的基本假设,同时也是一个很强的假设,在现实中很难得到保证;因此光流法得出的结果可能存在偏差 二、LK光流法 1、空间点在图像中的灰度

qq_42138662的博客 5458

LK光流法在无人机视觉避障中的实战:结合金字塔与反向光流提升跟踪鲁棒性

本文深入探讨了LK光流法在无人机视觉避障中的实战应用,结合金字塔多层光流与反向光流法提升跟踪鲁棒性。针对无人机高速飞行中的运动模糊、照度突变等挑战,提出了自适应金字塔层数选择、特征点预筛选策略及混合精度计算等优化方案,显著提高了算法在嵌入式设备上的实时性能与精度。

weixin_42531925的博客 418

视觉SLAM前端——LK光流法

目录: LK光流介绍 单层LK光流 多层LK光流 LK光流   LK光流是一种描述图像运动的方法,利用LK光流可以实现对图像的追踪,从而求解图像运动的位姿。其基本思想如下: 单层光流法 求解的基本流程如下: 1.特征点的选取 2.Gauss-Newton法求解Δx,Δy\Delta x,\Delta yΔx,Δy 关于特征点的选取,笔者前面写了一篇文章进行了详细介绍,这里不在赘述。 ...

qq_38023849的博客 2916

深蓝学院视觉SLAM第六次习题(上)

现在的内容更加注重实践,对于我来说也更加需要时间了,好难 1.LK 光流 1.1光流文献综述 问题: 按此文的分类,光流法可分为哪几类? 可将算法分类为加性算法(additive)或组合算法(compositional),以及正向算法(forwards)或逆算法(inverse) 在 compositional 中,为什么有时候需要做原始图像的 wrap?该 wrap 有何物理意义? 需要在当前位姿估计之前引入增量式 warp(incremental warp)以建立半群约束要求(the se

weixin_44218240的博客 2525

LK光流法在无人机视觉导航中的实战:如何用金字塔光流提升特征追踪的鲁棒性?

本文深入探讨了LK光流法在无人机视觉导航中的应用,重点介绍了金字塔多层光流架构如何提升特征追踪的鲁棒性。通过反向光流优化和自适应窗口策略,解决了无人机在复杂环境中的运动模糊、尺度变化和光照波动问题,显著提高了导航系统的精度和稳定性。

weixin_26789847的博客 375

别再死记硬背公式了!用OpenCV+C++手把手实现LK光流法(附反向光流优化技巧)

本文详细介绍了如何使用C++和OpenCV从零实现LK光流法,特别聚焦反向光流优化技巧。通过实战代码和性能对比,展示了金字塔多层光流和反向光流法在提升计算效率和精度方面的优势,适合计算机视觉开发者和研究者参考。

weixin_28683689的博客 336

LK金字塔光流法

基于OPENCV的光流法,使用的是LK金字塔算法

从原理到实践:金字塔LK光流法实现大运动像素追踪

光流法是计算机视觉中估计图像序列中像素点运动的核心技术,其基本原理基于亮度恒定和局部运动一致性假设,通过求解光流约束方程来追踪特征点的位移。该技术对于克服经典Lucas-Kanade算法的小运动局限具有重要价值,使其能够处理视频稳定、动作捕捉等实际应用中的大幅度运动。金字塔LK光流法通过构建图像金字塔,在顶层估算粗略运动后逐层细化,有效扩展了算法的运动捕捉范围。本文结合C++与OpenCV,详细解析了该算法的数学原理与实现细节,并提供了关键参数调优和工程实践指南,帮助开发者在自动驾驶、AR特效等场景中构建鲁

weixin_30985047的博客 340

calibre QRC提取寄生参数

typical将上面的文件QCI_flow里面的文件 在Cp 到当前 ,其实应该是某几个文件,但是我给忘记了 就全cp过来了 ,无影响,不过也希望大佬指正。

2202_75711937的博客 1515

Isaac Lab强化学习实战:用SO-ARM101机械臂实现抓取任务(附B站视频教程)

本文详细介绍了如何使用Isaac Lab强化学习框架,在SO-ARM101机械臂上实现抓取任务的完整实战流程。内容涵盖从环境搭建、奖励函数设计、训练调参到模型部署的各个环节,并分享了Sim-to-Real迁移的关键技巧,旨在帮助开发者高效完成机器人强化学习项目。

weixin_29070721的博客 1101

别再死记硬背公式了!用OpenCV+Eigen手把手实现LK光流法(附反向光流优化技巧)

本文详细介绍了如何使用OpenCV和Eigen库从零实现LK光流法,包括基础版本、金字塔优化和高效的反向光流法。通过代码示例和实战技巧,帮助读者深入理解光流法的核心原理和工程实践中的优化策略,特别适合计算机视觉开发者和研究者参考。

weixin_30236595的博客 377

东方财富网股票API逆向分析:手把手教你破解动态参数(2024最新版)

本文详细解析了2024年东方财富网股票API的动态参数生成机制,包括回调函数、身份验证和时效控制参数的逆向工程方法。通过实战代码演示,帮助开发者破解动态参数,实现高效稳定的股票数据爬取,适用于金融数据分析和量化交易场景。

weixin_29091105的博客 1024

深入解析金字塔Lucas-Kanade光流:从理论到C++实战

本文深入解析了金字塔Lucas-Kanade光流法的核心原理与C++实战。从亮度恒定、小运动、空间一致性三大假设出发,详细推导了光流约束方程,并重点阐述了如何通过构建图像金字塔,采用“由粗到精”的策略有效解决大位移跟踪难题。文章提供了从单层光流实现到完整金字塔迭代的详细C++代码,并分享了反向光流、特征点选择等工程优化技巧,是掌握这一经典计算机视觉算法的实用指南。

ol789012的博客 437

【机器学习】Anaconda安装后打不开jupyter notebook(网页不自动跳出)

anaconda安装成功以后,jupyter notebook可以出现打开的路径,能够手动复制粘贴地址路径打开,却不能自动跳转到网页。解决的办法是在配置文件中加入指定的浏览器配置信息。

weixin_43416960的博客 4万+

【AUTOSAR-COM】-5.2-“Deadline Monitoring超时监控”-2-基于IPdu实现

目录 1 在CFG中配置Deadline Monitoring超时监控 1.1 参数说明 1.2 生成代码差异 2 通过一段测试代码看Deadline Monitoring超时监控 3 使用CAN盒观察Deadline Monitoring实际测试效果 3.1 Case 1:ECU开始工作时,没有收到Frame 3.2 Case 2:ECU工作中,接收的Frame丢失、 4 小结 5 结尾 关键字: DM=Deadline Monitoring超时监控 ComFirstTime...

「汽车电子助手」的博客 1788

深蓝学院视觉slam十四讲第6章作业

每个像素的误差为第一张图像在特征点(x, y) 处的像素值减去第二张图像在(x+dx, y+dy) 处的像素值 记自变量为[Δx,Δy]T[\Delta x, \Delta y]^T[Δx,Δy]T,用中值查分表示图像梯度,导数为 [−dI2dΔx−dI2dΔy]=[−I2(x+Δx+1,y+Δy)−I2(x+Δx−1,y+Δy)2−I2(x+Δx,y+Δy+1)−I2(x+Δx,y+Δy−1)2]\begin{bmatrix} -\dfrac{d I_2}{d\Delta x} \\ \\ -\d..

Jevin-L的博客 2520

ardupilot 为什么要采样四元数姿态控制

本节主要说明清楚ardupilot姿态控制为什么要用到四元数,欢迎批评指正!!!

陌城烟雨 1117

光流法原理与工程实践:从约束方程到LK/HS与金字塔

光流法是计算机视觉中从相邻帧亮度变化估计像素位移的技术,常用于运动估计、目标跟踪、视频稳像和帧插值。其原理基于亮度恒定与小运动假设推导光流约束方程,并通过局部窗口或全局平滑补足欠定解。工程价值在于输出帧间运动矢量场,但实际落地需在LK、HS、Farneback等算法间选型,借助金字塔处理大位移,并关注参数配置、帧率标定和前后向一致性校验。应用涵盖特征点跟踪、工业传送带测速、显微细胞迁移分析等场景。围绕光流法的公式推导、算法取舍与可运行实现链路,梳理常见失效原因与排查方法。

weixin_33708633的博客 192

AUTOSAE软件配置-项目标准配置 (PSC) 导入达芬奇( DaVinci Configurator)

文件是“可拆分的”,这意味着如果格式符合 AUTOSAR 拆分规则,则可以与其他。)是一个ARXML文件,主要由OEM提供,其中包含。)工件,可以作为输入文件导入到达芬奇配置器专业版。导入的参数将以只读方式处理。不允许在多个 ARXML 文件中导入一个。的已存在数据或从输入文件派生的数据。可以作为输入文件导入到另一个。文件会覆盖用户配置的基本。元素和诊断数据预配置。定义 [数据结构]。中,可以导出一个或多个。

m0_49148264的博客 1003

使用 Simulink/Simscape Electrical/Stateflow,构建一个并网逆变器短路故障动态响应与恢复策略仿真模型

本文基于Simulink平台,详细介绍了并网逆变器短路故障的动态响应与恢复策略仿真方法。主要内容包括:1)构建包含热模型的高精度逆变器模型;2)模拟IGBT击穿和桥臂直通两种短路故障;3)设计基于Stateflow的微秒级快速保护逻辑;4)实现放电、去磁、自检、重启的完整恢复流程。仿真结果表明,所提出的保护方案能在200μs内有效限制故障电流,避免器件永久损坏,并通过标准化恢复流程实现系统安全重启。文章还探讨了硬件保护协同、多级保护和预测保护等高级策略,为电力电子系统安全防护提供了实用解决方案。

xiaoheshang_123的博客 107
上一篇: leetcode 20. Valid Parentheses(有效括号)
下一篇: leetcode 1249. Minimum Remove to Make Valid Parentheses(移除最少的无效括号)
蓝羽飞鸟
博客等级 码龄8年 1万+粉丝 727原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值