使用Matlab、Opencv、Ros三种方法完成相机标定

这篇具有很好参考价值的文章主要介绍了使用Matlab、Opencv、Ros三种方法完成相机标定。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前置知识总结

1、相机标定的意义

        在机器视觉领域,相机的标定是一个关键的环节,它决定了机器视觉系统能否有效的定位,能否有效的计算目标物。相机标定意义在于将现实世界中的三维物体与相机图像对应的二维物体映射起来,实际上就是透视投影。

2、相机标定原理

        针对针孔相机模型, 相机标定,标定的是指内参矩阵和外参矩阵,就可以确定为一的相机模型。

  • 相机的内参: 主要包含 焦距,相机主点坐标,以及畸变参数即 fx fy  cx cy k1 k2 k3 p1 p2
  • 相机的外参: 包含 旋转矩阵和平移矩阵 即 R  t     

 2、相机成像几何模型

  • 世界坐标系:是客观三维世界的绝对坐标系,也称客观坐标系。
  • 相机坐标系(光心坐标系):以相机的光心为坐标原点, X 轴和 Y 轴分别平行于图像坐标系的 X 轴和 Y 轴,相机的光轴为 Z 轴。
  • 图像坐标系:以图像平面的中心为坐标原点,X 轴和 Y 轴分别平行于图像平面的两条垂直边, 用( x , y )表示其坐标值。 图像坐标系是用物理单位(例如毫米)表示像素在图像中的位置。
  • 像素坐标系:以图像平面的左上角顶点为原点,X 轴和 Y 轴分别平行于图像坐标系的 X 轴和 Y 轴,用(u , v )表示其坐标值,单位是像素。

3、相机内外参基本原理    

        相机坐标系世界坐标系之间的坐标转换关系称为相机外参,一般由平移旋转两部分参数组成。求取外参的过程称之为外参标定,外参标定的结果关系到如何引导机器人进行抓取。
        相机内部参数(简称内参)只与相机内部属性(如焦距、分辨率、像素尺寸、镜头畸变等)
有关。利用相机内参可以将相机坐标系中的三维空间点变换到图像平面坐标系中,经过镜头畸变等校正过程之后可进一步变换至图像像素坐标系中的二维像素点。求取这一关系的
过程称为相机内参标定。
csdn 相机标定,matlab,opencv,linux

4、相机内参矩阵推导   

4.1 相机坐标系–>图像坐标系

        真实世界中的某点会投影在相机的成像平面上,利用针孔成像原理,空间任意一点Pc与图像点p之间的关系,Pc与相机光心Oc的连线为OcPc,与像面的交点p即为空间点Pc在图像平面上的投影。

csdn 相机标定,matlab,opencv,linux

        该过程为透视投影,利用相似三角形关系可得:

csdn 相机标定,matlab,opencv,linux

        其中f为焦距,z轴方向上s为Pc点到光心的距离,一般称为比例因子。投影关系为写成矩阵形式:

csdn 相机标定,matlab,opencv,linux

        其中,s为比例因子(s不为0),f为有效焦距(光心到图像平面的距离),(x,y,z,1)T是空间点P在坐标系oxyz中的齐次坐标,(x,y,1)T是像点p在图像坐标系OXY中的齐次坐标。

        注意:此时投影点p的单位还是mm,并不是pixel,需要进一步转换到像素坐标系。

4.2、图像坐标系–>像素平面坐标系

       像素坐标系和图像坐标系都在成像平面上,只是各自的原点和度量单位不一样。图像坐标系的原点为相机光轴与成像平面的交点,通常情况下是成像平面的中点或者叫principal point。图像坐标系的单位是mm,属于物理单位,而像素坐标系的单位是pixel,我们平常描述一个像素点都是几行几列。所以这二者之间的转换如下:

csdn 相机标定,matlab,opencv,linux

dx和dy表示每一列和每一行分别代表多少mm,即1pixel=dx mm。

5、相机透镜畸变与校正

5.1、径向畸变

 光线经过透镜中心会发生弯曲,这种现象称为径向畸变,径向畸变分为枕型畸变与筒形畸变。

csdn 相机标定,matlab,opencv,linux

  径向畸变围绕像素坐标及其泰勒展开式进行矫正。     

csdn 相机标定,matlab,opencv,linux

 其中(,)为矫正之后的坐标, (x,y)代表畸变像素坐标, r 代表成像中心距离,

5.2、切向畸变

相机畸变除了会产生径向畸变之外而且会产生切向畸变,透镜与成像平面不完全平行造成切向畸变的发生。

csdn 相机标定,matlab,opencv,linux

      切向畸变的矫正公式:

csdn 相机标定,matlab,opencv,linux

6、棋盘格图片采集

        分享一个可以生成各种标定板的网站: https://calib.io/pages/camera-calibration-pattern-generatorSingle Camera Calibrator App​​​​​​https://calib.io/pages/camera-calibration-pattern-generatorSingle Camera Calibrator App​​​​​​

和自定义检测器图案。有关这些图案的细节和包含可打印图案的PDF文件,请参见校准图案。

二、使用Opencv 获得图片

import cv2 as cv

print(cv.__version__)

def videoDemo():
    capture = cv.VideoCapture(0)
    n = 0
    while True:
        ret, frame = capture.read()
        n = n + 1
        print(f"num {n} {ret}")
        cv.imshow("Video", frame)
        c = cv.waitKey(50)
        if c == 32:
            cv.destroyAllWindows()
            cv.imwrite("/home/dofbot/camera/pic/borad.png", frame)
            cv.imshow("Video", frame)
            break

if __name__ == '__main__':
    videoDemo()

三、Matlab 

        支持棋盘格、圆圈格在APP中选择Camera Calibrator,如下:

csdn 相机标定,matlab,opencv,linux

        点击 Add Images,导入拍照图片。标定20张左右就够了,然后角度变一下,但不需要变太大,太大了会影响标定效果。标定板最好在视场中心,且占据较大面积。 

csdn 相机标定,matlab,opencv,linux

        修改棋盘格大小为27*27mm(我的A4纸测量是这样)

csdn 相机标定,matlab,opencv,linux

         对于标准相机,菜单栏的option里选择三阶径向畸变和斜切:

csdn 相机标定,matlab,opencv,linux

        点击Calibrate,进行相机标定:
        右上角是重建平均误差,只要平均误差小于0.5,就可以认为这是相机标定的结果是可靠的。

csdn 相机标定,matlab,opencv,linux

        把相机参数导出来,点击 Export Camera Parameters。点击确定,就可以看到matlab工作区出现了相机参数。点开这个参数,就可以得到相机的各个参数: 

csdn 相机标定,matlab,opencv,linux

四、Opencv

        为了找到棋盘的图案,使⽤函数 cv2.findChessboardCorners()。还需要传⼊图案的类型⽐如说 8x8 的格⼦或 5x5 的格⼦等。在本例中我们使⽤的9×6 的格⼦。(通常情况下棋盘都是 8x8 或者7x7)。它会返回⻆点,如果得到图像的话返回值类型(Retval)就会是 True。这些⻆点会按顺序排列(从左到右,从上到下)。 在找到这些⻆点之后我们可以使⽤函数 cv2.cornerSubPix() 增加准确度。我们使⽤函数cv2.drawChessboardCorners() 绘制图案。

        在得到了这些对象点和图像点之后,我们已经准备好来做摄像机标定了。我们要使⽤的函数是cv2.calibrateCamera()。它会返回摄像机矩阵,畸变系数,旋转和变换向量等。

所有的这些步骤都被包含在下⾯的代码中了:

import cv2
import numpy as np
import glob

# 找棋盘格⻆点
# 设置寻找亚像素⻆点的参数,采⽤的停⽌准则是最⼤循环次数30和最⼤误差容限0.001
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)  # 阈值
#棋盘格模板规格
w = 9   # 10 - 1
h = 6   # 7 - 1
# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为⼆维矩阵
objp = np.zeros((w*h, 3), np.float32)
objp[:, :2] = np.mgrid[0:w,0:h].T.reshape(-1, 2)
objp = objp*18.1  # 18.1 mm

# 储存棋盘格⻆点的世界坐标和图像坐标对
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平⾯的⼆维点
#加载pic⽂件夹下所有的jpg图像
images = glob.glob('D:\pic\*.png') # 拍摄的⼗⼏张棋盘图⽚所在⽬录

i = 0
for fname in images:
    img = cv2.imread(fname)
    # 获取画⾯中⼼点
    #获取图像的⻓宽
    h1, w1 = img.shape[0], img.shape[1]
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    u, v = img.shape[:2]
    # 找到棋盘格⻆点
    ret, corners = cv2.findChessboardCorners(gray, (w, h), None)
    # 如果找到⾜够点对,将其存储起来
    if ret == True:
        print("i:", i)
        i = i+1
        # 在原⻆点的基础上寻找亚像素⻆点
        cv2.cornerSubPix(gray,corners, (11, 11), (-1, -1), criteria)
        #追加进⼊世界三维点和平⾯⼆维点中
        objpoints.append(objp)
        imgpoints.append(corners)
        # 将⻆点在图像上显⽰
        cv2.drawChessboardCorners(img, (w, h), corners, ret)
        cv2.namedWindow('findCorners', cv2.WINDOW_NORMAL)
        cv2.resizeWindow('findCorners', 640, 480)
        cv2.imshow('findCorners', img)
        cv2.waitKey(200)
cv2.destroyAllWindows()
#%% 标定
print('正在计算')
#标定
ret, mtx, dist, rvecs, tvecs = \
    cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

print("ret:", ret)
print("mtx:\n", mtx)  # 内参数矩阵
print("dist畸变值:\n", dist)  # 畸变系数 distortion cofficients = (k_©,k_ª,p_©,p_ª,k_«)
print("rvecs旋转(向量)外参:\n", rvecs)  # 旋转向量 # 外参数
print("tvecs平移(向量)外参:\n", tvecs)  # 平移向量 # 外参数
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (u, v), 0, (u, v))
print('newcameramtx外参', newcameramtx)

五、Ros 

5.1 使用ROS usb_cam驱动相机

5.1.1 安装usbcam

Kinetic:

sudo apt-get install ros-kinetic-usb-cam

Melodic:

sudo apt-get install ros-melodic-usb-cam

其他版本

sudo apt-get install ros-版本名称-usb-cam
4.1.2 修改launch文件

进入目录:

roscd usb_cam
cd launch
sudo gedit usb_cam-test.launch 

目前主要修改device和width两个参数,可以使用ls /dev/video*查看系统视频设备。

<launch>
  <node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
    <!-- modify the video device to your device -->
    <param name="video_device" value="/dev/video0" />
    <!-- modify the size of your device -->
    <param name="image_width" value="1280" />
    <param name="image_height" value="720" />
    <param name="pixel_format" value="yuyv" />
    <param name="camera_frame_id" value="usb_cam" />
    <param name="io_method" value="mmap"/>
  </node>
  <node name="image_view" pkg="image_view" type="image_view" respawn="false" ou$
    <remap from="image" to="/usb_cam/image_raw"/>
    <param name="autosize" value="true" />
  </node>
</launch>
c. 启动相机
roslaunch usb_cam usb_cam-test.launch

5.2 使用ROS进行相机标定

5.2.1 ros使用相机usb_cam标定内参。
  • 标定完成后点击Save可以保存标定所用的图片和参数矩阵。在终端里会输出标定产生的压缩包,默认放在/tmp目录下。
5.2.2 查看摄像头设备名
ls /dev/video*

选择自己需要显示的设备,再修改launch文件,就可以使用。

csdn 相机标定,matlab,opencv,linux

查看相机接口信息

v4l2-ctl -d 0 --all

csdn 相机标定,matlab,opencv,linux

参考相机接口信息修改usb_cam-test.launch文件,文件原内容如下

<launch>
  <node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
    <param name="video_device" value="/dev/video0" />
    <param name="image_width" value="640" />
    <param name="image_height" value="480" />
    <param name="pixel_format" value="yuyv" />
    <param name="camera_frame_id" value="usb_cam" />
    <param name="io_method" value="mmap"/>
  </node>
  <node name="image_view" pkg="image_view" type="image_view" respawn="false" output="screen">
    <remap from="image" to="/usb_cam/image_raw"/>
    <param name="autosize" value="true" />
  </node>
</launch>

 运行修改后的launch文件即可

roslaunch usb_cam usb_cam-test.launch

打开标定窗口

一般来说正常安装ros都是包含了camera_calibration,输入下面命令检查一下

rosdep install camera_calibration #All required rosdeps installed successfully

运行前需要根据你的棋盘格修改参数

  • 一个是size参数为棋盘格内角点数量比如8x9=72个格子的棋盘格,角点个数为7x8=63个,size参数就要写7x8
  • 另外一个参数为square,传入的参数为棋盘格一个小格子的宽度(注意单位为m
  • image,图像话题的原始数据默认为camera:=/usb_cam
rosrun camera_calibration cameracalibrator.py --size 10x7 --square 0.015 image:=/usb_cam/image_raw camera:=/usb_cam
5.2.3 生成标定文件

标定完成后点击Calculate会稍微有点卡顿,不要担心后台正在进行标定,完成后下面的SAVE和COMMIT按钮变为可用状态,点击SAVE即可保存标定完成后的文件。

点击commit即可把标定文件存储到系统的~/.ros/camera_info/xxx.yaml目录(Ctrl+H 显示隐藏的目)

5.2.4 在ROS中使用该参数

可以在usb_cam的launch文件中增加以下参数,重新启动usb_cam节点,即可使用该标定参数。

参数值小鱼这里写的是file:///home/dev/.ros/camera_info/ost.yaml,可打开目录~/.ros/camera_info/进行查看

<param name="camera_info_url" type="string" value="file:///home/dev/.ros/camera_info/ost.yaml"/>

5.3.3 开始运行

source devel/setup.bash
roslaunch handeye-calib aruco_start_usb_cam.launch

六、 相机信息中的内参相关内容

以Intel Realsense彩色相机为例,以下是彩色相机的信息。

# rostopic echo /right_arm_camera/color/camera_info
---
header: 
  seq: 32308
  stamp: 
    secs: 1694683940
    nsecs: 530882359
  frame_id: "right_arm_camera_color_optical_frame"
height: 720
width: 1280
distortion_model: "plumb_bob"
D: [0.0, 0.0, 0.0, 0.0, 0.0]
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]
R: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]
binning_x: 0
binning_y: 0
roi: 
  x_offset: 0
  y_offset: 0
  height: 0
  width: 0
  do_rectify: False
---
header: 
  seq: 32309
  stamp: 
    secs: 1694683940
    nsecs: 564413071
  frame_id: "right_arm_camera_color_optical_frame"
height: 720
width: 1280
distortion_model: "plumb_bob"
D: [0.0, 0.0, 0.0, 0.0, 0.0]
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]
R: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]
binning_x: 0
binning_y: 0
roi: 
  x_offset: 0
  y_offset: 0
  height: 0
  width: 0
  do_rectify: False
---

其中包括相机的内部参数有关的参数:

当处理相机内参时,常见的三个参数是 D、K 和 P,此外相关的还有畸变模型。

6.1、D畸变系数(distortion_coefficients):

D 是一个通常包含五个元素的数组 [k1, k2, p1, p2, k3],用于描述相机图像中的径向和切向畸变。

  • k1 和 k2 是径向畸变系数,它们用于描述镜头的弯曲形状,通常是负数。
  • p1 和 p2 是切向畸变系数,它们用于描述镜头的畸变不对称性,通常是很小的值。
  • k3 是一个更高阶的径向畸变系数,通常情况下很小,有时甚至可以忽略。
D: [0.0, 0.0, 0.0, 0.0, 0.0]

6.2、K相机内参矩阵(camera_matrix):

K 是一个3x3的矩阵,它包括了相机的内部参数,用于将相机坐标系中的三维点映射到图像平面上的二维坐标。

K 的主要元素包括:

  • K[0] 和 K[4] 是焦距在图像 x 和 y 轴上的分量,通常以像素为单位。
  • K[2] 和 K[5] 是光心在图像 x 和 y 轴上的坐标,也以像素为单位。
  • K[8] 通常是1,是一个归一化参数。
  • K 包含了焦距和主点的信息。
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]

6.3、P投影矩阵(projection_matrix):

P 是一个3x4的矩阵,包含了相机的投影参数,用于将相机坐标系中的三维点映射到图像坐标系。

P 的元素包括了内参和外参信息。

  • 其中 P[0] 和 P[5] 分别对应于焦距 fx 和 fy,用于将相机坐标系的 x 和 y 坐标映射到图像坐标系上。
  • P[2] 和 P[6] 对应于光心的 x 和 y 坐标 cx 和 cy。
  • P[3] 和 P[7] 通常为0,用于表示没有视角的旋转或平移。
  • P[10] 通常是1,是一个归一化参数。
  • 投影矩阵 P包含了相机的内部参数和畸变参数。
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]

6.4、distortion_model"(畸变模型):

distortion_model 是相机标定信息中的一个字段,用于描述相机的畸变模型。
畸变模型是用来描述相机镜头产生的畸变效应的数学模型。
在计算机视觉中,畸变通常分为径向畸变和切向畸变两种主要类型,而畸变模型用于对这些畸变进行建模和校正。
Plumb Bob (钉形畸变模型):
“plumb_bob” 畸变模型是最常见的畸变模型之一,也是默认的畸变模型。它通常用于描述径向畸变(Radial Distortion)和切向畸变(Tangential Distortion)。
径向畸变主要是由于镜头形状不完全圆形引起的,导致图像中心附近的像素与图像边缘的像素之间存在畸变。这种畸变通常用多项式函数建模。
切向畸变则是由于相机镜头不完全平行于图像平面引起的,导致图像中心附近的像素存在畸变。切向畸变通常也用多项式函数建模。
“plumb_bob” 畸变模型使用径向和切向畸变系数(D)来描述这两种畸变。文章来源地址https://www.toymoban.com/news/detail-849761.html

到了这里,关于使用Matlab、Opencv、Ros三种方法完成相机标定的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于虚拟机安装Ubuntu18.04+ROS的2D相机或电脑自带摄像头的在线标定方法

    硬件 :笔记本电脑自带摄像头或者通过usb接口连接的相机 软件 :虚拟机+ubuntu18.04+ROS1 melodic(针对ubuntu18.04对应的ROS版本) 首先确保在主目录下,创建ROS工程 克隆代码 编译代码 这个地方我报错了 – No package ‘libv4l2’ found CMake Error at /usr/share/cmake-3.10/Modules/FindPkgConfig.cmake:419

    2024年02月02日
    浏览(46)
  • Opencv 相机内参标定及使用

    目录 一、功能描述 二、标定板制作 三、图像采集 四、标定内参 方法一:Matlab标定  方法二:C++程序标定 五、使用内参 1.本文用于记录通过 Opencv 进行相机内参标定和对内参的使用来进行图像畸变矫正。         1)相机矩阵:包括焦距(fx,fy),光学中心(Cx,Cy),完

    2024年01月24日
    浏览(28)
  • 使用ROS功能包camera_calibration进行单目相机和双目相机的内参和外参标定

    本文总结使用ROS标定单目和双目相机的过程,同时提供生成棋盘格文件的方法。 参考链接: [1]使用ros标定相机的内参和外参 [2]ROS下采用camera_calibration进行双目相机标定 棋盘格可以自己买一个,或者打印一个粘在板子上,棋盘格电子版生成可以参考博客《使用kalibr标定工具进

    2024年02月11日
    浏览(32)
  • 使用opencv实现单目标定相机标定(摘抄)

    使用opencv实现单目标定 相机标定的目的 :获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像。 相机标定的输入 :标定图像上所有内角点的图像坐标,标定板图

    2024年02月11日
    浏览(40)
  • 使用opencv做双目测距(相机标定+立体匹配+测距)

    最近在做双目测距,觉得有必要记录点东西,所以我的第一篇博客就这么诞生啦~ 双目测距属于立体视觉这一块,我觉得应该有很多人踩过这个坑了,但网上的资料依旧是云里雾里的,要么是理论讲一大堆,最后发现还不知道怎么做,要么就是直接代码一贴,让你懵逼。 所以

    2024年01月20日
    浏览(26)
  • Matlab相机标定——使用Single Camera Calibrator App

     什么是相机标定?​​​​​​​         Single Camera Calibrator App支持棋盘格、圆圈格和自定义检测器图案。有关这些图案的细节和包含可打印图案的PDF文件,请参见校准图案。 分享一个可以生成各种标定板的网站:https://calib.io/pages/camera-calibration-pattern-generator (1)本文

    2024年02月04日
    浏览(38)
  • ROS进行深度相机的标定

    自己使用标定板对深度相机进行标定。 参考:http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration 在下面的网站中可下载棋盘格标定板,可用A4纸打印下来。 http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration?action=AttachFiledo=viewtarget=check-108.pdf 1.1 进入ROS内核 1.2 打开相机

    2024年02月09日
    浏览(45)
  • ROS学习——利用电脑相机标定

    一、 安装usb-cam包和标定数据包 要把kinetic改成你自己的ros版本 。 二、启动相机 就会出现一个界面  可以通过下面命令查看相机发布了哪些参数:  可以通过下面命令查看发布消息的具体类型: 我们可以看到发布者和接收者: 三、启动相机标定包 出现黑白相机  四、进行相

    2024年02月10日
    浏览(35)
  • 使用opencv-python(cv2)库进行相机标定

    2023年09月11日
    浏览(42)
  • 【ROS】usb_cam相机标定

    1. 唠叨两句 当我们要用相机做测量用途时,就需要做相机标定了,不然得到的计算结果会有很大误差,标定的内容包括三部分:内参,外参还有畸变参数。所以标定的过程就是要求得上面这些参数。 以前弄这个事估计挺麻烦,需要做实验和计算才能得到,现在通过ros的开源

    2024年02月08日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包