SURF特征提取算法详解

article/2025/9/28 16:24:06

上一节我们已经介绍了SIFT算法,SIFT算法对旋转、尺度缩放、亮度变化等保持不变性,对视角变换、仿射变化、噪声也保持一定程度的稳定性,是一种非常优秀的局部特征描述算法。但是其实时性相对不高。

SURF(Speeded Up Robust Features)算法改进了特征了提取和描述方式,用一种更为高效的方式完成特征点的提取和描述。

一 使用快速Hessian算法和SURF来提取和检测特征

我们先用OpenCV库函数演示一下快速Hessian算法和SURF来提取的效果,然后再来讲述一下SURF算法的原理。

SURF特征检测算法由Herbert Lowe于2006年发表,该算法比SIFT算法快好几倍,它吸收了SIFT算法的思想。

SURF算法采用快速Hessian算法检测关键点,而SURF算子会通过一个特征向量来描述关键点周围区域的情况。这和SIFT算法很像,SIFT算法分别采用DoG和SIFT算子来检测关键点和提取关键点的描述符。下面我们来演示一个例子:

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Aug 24 20:09:32 2018
  4. @author: lenovo
  5. """
  6. # -*- coding: utf-8 -*-
  7. """
  8. Created on Wed Aug 22 16:53:16 2018
  9. @author: lenovo
  10. """
  11. '''
  12. SURF算法
  13. '''
  14. import cv2
  15. import numpy as np
  16. img = cv2.imread('./image/cali.bmp')
  17. img = cv2.resize(img,dsize=(600,400))
  18. #转换为灰度图像
  19. gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  20. #创建一个SURF对象
  21. surf = cv2.xfeatures2d.SURF_create(20000)
  22. #SIFT对象会使用Hessian算法检测关键点,并且对每个关键点周围的区域计算特征向量。该函数返回关键点的信息和描述符
  23. keypoints,descriptor = surf.detectAndCompute(gray,None)
  24. print(type(keypoints),len(keypoints),keypoints[0])
  25. print(descriptor.shape)
  26. #在图像上绘制关键点
  27. img = cv2.drawKeypoints(image=img,keypoints = keypoints,outImage=img,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  28. #显示图像
  29. cv2.imshow('surf_keypoints',img)
  30. cv2.waitKey(0)
  31. cv2.destroyAllWindows()

我们把Hessian阈值设置为20000,阈值越高,能识别的特征就越少,因此可以采用试探法来得到最优检测。

二 SURF算法原理

1、SURF特征检测的步骤

  1. 尺度空间的极值检测:搜索所有尺度空间上的图像,通过Hessian来识别潜在的对尺度和选择不变的兴趣点。
  2. 特征点过滤并进行精确定位。
  3. 特征方向赋值:统计特征点圆形邻域内的Harr小波特征。即在60度扇形内,每次将60度扇形区域旋转0.2弧度进行统计,将值最大的那个扇形的方向作为该特征点的主方向。
  4. 特征点描述:沿着特征点主方向周围的邻域内,取4×44×4个矩形小区域,统计每个小区域的Haar特征,然后每个区域得到一个4维的特征向量。一个特征点共有64维的特征向量作为SURF特征的描述子。

2、构建Hessian(黑塞矩阵)

构建Hessian矩阵的目的是为了生成图像稳定的边缘点(突变点),跟Canny、拉普拉斯边缘检测的作用类似,为特征提取做准备。构建Hessian矩阵的过程对应着SIFT算法中的DoG过程。

黑塞矩阵(Hessian Matrix)是由一个多元函数的二阶偏导数构成的方阵,描述了函数的局部曲率。由德国数学家Ludwin Otto Hessian于19世纪提出。

对于一个图像I(x,y)I(x,y),其Hessian矩阵如下:

H(I(x,y))=\begin{bmatrix} \frac{\partial^2I}{\partial{x^2}} & \frac{\partial^2I}{\partial{x}\partial{y}} \\ \frac{\partial^2I}{\partial{x}\partial{y}} & \frac{\partial^2I}{\partial{y^2}} \end{bmatrix}

H矩阵的判别式是:

Det(H)=\frac{\partial^2I}{\partial{x^2}}*\frac{\partial^2I}{\partial{y^2}}-\frac{\partial^2I}{\partial{x}\partial{y}} * \frac{\partial^2I}{\partial{x}\partial{y}}

在构建Hessian矩阵前需要对图像进行高斯滤波,经过滤波后的Hessian矩阵表达式为:

H(x,y,\sigma)=\begin{bmatrix} L_{xx}(x,y,\sigma) & L_{xy}(x,y,\sigma) \\ L_{xy}(x,y,\sigma) & L_{yy}(x,y,\sigma) \end{bmatrix}

其中(x,y)为像素位置,L(x,y,\sigma)=G(\sigma)*I(x,y),代表着图像的高斯尺度空间,是由图像和不同的高斯卷积得到。

我们知道在离散数学图像中,一阶导数是相邻像素的灰度差:

L_x=L(x+1,y)-L(x,y)

二阶导数是对一阶导数的再次求导:

L_{xx}=[L(x+1,y)-L(x,y)]-[L(x,y)-L(x-1,y)]

=L(x+1,y)+L(x-1,y)-2L(x,y)

反过来看Hessian矩阵的判别式,其实就是当前点对水平方向二阶偏导数乘以垂直方向二阶偏导数再减去当前水平、垂直二阶偏导的二次方:

Det(H)=L_{xx}*L_{yy}-L_{xy}*L_{xy}

通过这种方法可以为图像中每个像素计算出其H行列式的决定值,并用这个值来判别图像局部特征点。Hession矩阵判别式中的L(x,y)L(x,y)是原始图像的高斯卷积,由于高斯核服从正太分布,从中心点往外,系数越来越小,为了提高运算速度,SURF算法使用了盒式滤波器来替代高斯滤波器L,所以在L_{xy}上乘了一个加权系数0.9,目的是为了平衡因使用盒式滤波器近似所带来的误差,则H矩阵判别式可表示为:

Det(H)=L_{xx}*L_{yy}-(0.9*L_{xy})^2

盒式滤波器和高斯滤波器的示意图如下:

上面两幅图是9*9高斯滤波器模板分别在图像垂直方向上二阶导数L_{yy}L_{xy}对应的值,下边两幅图是使用盒式滤波器对其近似,灰色部分的像素值为0,黑色为-2,白色为1.

那么为什么盒式滤波器可以提高运算速度呢?这就涉及到积分图的使用,盒式滤波器将图像的滤波转化成计算图像上不同区域间像素的加减运算问题,这正是积分图的强项,只需要简单积分查找积分图就可以完成。

3、构造尺度空间

同SIFT算法一样,SURF算法的尺度空间由O组S层组成,不同的是,SIFT算法下一组图像的长宽均是上一组的一半,同一组不同层图像之间尺寸一样,但是所使用的尺度空间因子(高斯模糊系数σ)逐渐增大;而在SURF算法中,不同组间图像的尺寸都是一致的,不同的是不同组间使用的盒式滤波器的模板尺寸逐渐增大,同一组不同层图像使用相同尺寸的滤波器,但是滤波器的尺度空间因子逐渐增大。如下图所示:

4、特征点过滤并进行精确定位

SURF特征点的定位过程和SIFT算法一致,将经过Hessian矩阵处理的每个像素点(即获得每个像素点Hessian矩阵的判别式值)与其图像域(相同大小的图像)和尺度域(相邻的尺度空间)的所有相邻点进行比较,当其大于(或者小于)所有相邻点时,该点就是极值点。如图所示,中间的检测点要和其所在图像的3×3邻域8个像素点,以及其相邻的上下两层3×3邻域18个像素点,共26个像素点进行比较。

初步定位出特征点后,再经过滤除能量比较弱的关键点以及错误定位的关键点,筛选出最终的稳定的特征点。

 

 5、计算特征点主方向

SIFT算法特征点的主方向是采用在特征点邻域内统计其梯度直方图,横轴是梯度方向的角度,纵轴是梯度方向对应梯度幅值的累加,取直方图bin最大的以及超过最大80%的那些方向作为特征点的主方向。

而在SURF算法中,采用的是统计特征点圆形邻域内的Harr小波特征,即在特征点的圆形邻域内,统计60度扇形内所有点的水平、垂直Harr小波特征总和,然后扇形以0.2弧度大小的间隔进行旋转并再次统计该区域内Harr小波特征值之后,最后将值最大的那个扇形的方向作为该特征点的主方向。该过程示意图如下:

Harr特征的具体内容可以参考第九节、人脸检测之Haar分类器。

6、生成特征描述

在SIFT算法中,为了保证特征矢量的旋转不变性,先以特征点为中心,在附近邻域内将坐标轴旋转θ(特征点的主方向)角度,然后提取特征点周围4×4个区域块,统计每小块内8个梯度方向,这样一个关键点就可以产生128维的SIFT特征向量。

SURF算法中,也是提取特征点周围4×4个矩形区域块,但是所取得矩形区域方向是沿着特征点的主方向,而不是像SIFT算法一样,经过旋转θθ角度。每个子区域统计25个像素点水平方向和垂直方向的Haar小波特征,这里的水平和垂直方向都是相对主方向而言的。该Harr小波特征为水平方向值之和、垂直方向值之和、水平方向值绝对值之和以及垂直方向绝对之和4个方向。该过程示意图如下:

把这4个值作为每个子块区域的特征向量,所以一共有4×4×4=64维向量作为SURF特征的描述子,比SIFT特征的描述子减少了一半。

三 特征点匹配

与SIFT特征点匹配类似,SURF也是通过计算两个特征点间特征向量的欧氏距离来确定匹配度,欧式距离越短,代表两个特征点的匹配度越好。不同的是SURF还加入了Hessian矩阵迹(矩阵特征值的和)的判断,如果两个特征点的矩阵迹正负号相同,代表着两个特征点具有相同方向上的对比度变化,如果不同,说明这两个特征点的对比度方向是相反的,即使欧氏距离为0,也直接剔除。

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Aug 24 20:09:32 2018
  4. @author: lenovo
  5. """
  6. # -*- coding: utf-8 -*-
  7. """
  8. Created on Wed Aug 22 16:53:16 2018
  9. @author: lenovo
  10. """
  11. '''
  12. SURF算法
  13. '''
  14. import cv2
  15. import numpy as np
  16. '''1、加载图片'''
  17. img1 = cv2.imread('./image/cali1.bmp',cv2.IMREAD_GRAYSCALE)
  18. img1 = cv2.resize(img1,dsize=(600,400))
  19. img2 = cv2.imread('./image/cali2.bmp',cv2.IMREAD_GRAYSCALE)
  20. img2 = cv2.resize(img2,dsize=(600,400))
  21. image1 = img1.copy()
  22. image2 = img2.copy()
  23. '''2、提取特征点'''
  24. #创建一个SURF对象
  25. surf = cv2.xfeatures2d.SURF_create(25000)
  26. #SIFT对象会使用Hessian算法检测关键点,并且对每个关键点周围的区域计算特征向量。该函数返回关键点的信息和描述符
  27. keypoints1,descriptor1 = surf.detectAndCompute(image1,None)
  28. keypoints2,descriptor2 = surf.detectAndCompute(image2,None)
  29. print('descriptor1:',descriptor1.shape,'descriptor2',descriptor2.shape)
  30. #在图像上绘制关键点
  31. image1 = cv2.drawKeypoints(image=image1,keypoints = keypoints1,outImage=image1,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  32. image2 = cv2.drawKeypoints(image=image2,keypoints = keypoints2,outImage=image2,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  33. #显示图像
  34. cv2.imshow('surf_keypoints1',image1)
  35. cv2.imshow('surf_keypoints2',image2)
  36. cv2.waitKey(20)
  37. '''3、特征点匹配'''
  38. matcher = cv2.FlannBasedMatcher()
  39. matchePoints = matcher.match(descriptor1,descriptor2)
  40. print(type(matchePoints),len(matchePoints),matchePoints[0])
  41. #提取强匹配特征点
  42. minMatch = 1
  43. maxMatch = 0
  44. for i in range(len(matchePoints)):
  45. if minMatch > matchePoints[i].distance:
  46. minMatch = matchePoints[i].distance
  47. if maxMatch < matchePoints[i].distance:
  48. maxMatch = matchePoints[i].distance
  49. print('最佳匹配值是:',minMatch)
  50. print('最差匹配值是:',maxMatch)
  51. #获取排雷在前边的几个最优匹配结果
  52. goodMatchePoints = []
  53. for i in range(len(matchePoints)):
  54. if matchePoints[i].distance < minMatch + (maxMatch-minMatch)/16:
  55. goodMatchePoints.append(matchePoints[i])
  56. #绘制最优匹配点
  57. outImg = None
  58. outImg = cv2.drawMatches(img1,keypoints1,img2,keypoints2,goodMatchePoints,outImg,matchColor=(0,255,0),flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT)
  59. cv2.imshow('matche',outImg)
  60. cv2.waitKey(0)
  61. cv2.destroyAllWindows()

 

我们来看一看特征点匹配效果,可以看到好多点都匹配错误,这主要与我选择的图片有关,由于我选择的图片是用来做相机标点的,而当我们使用SURF算法提取特征点,图片上大部分特征点都具有相同的性质,特征向量也近似相等,因此在匹配时会出现很大的误差。

下面我们更换两张图片,再次进行特征点匹配:

我们可以看到这个匹配效果比刚才好了不少,而且我对Hessian阈值也进行了修改,这个值需要自己不断的调整,以达到自己的期望。但是总体上来看,我们选择的这两幅图片亮度和对比度差异都是很大的,而且拍摄所使用的相机也是不同的,左侧是我自己用手机拍摄到的,右侧是从网上下载的,匹配能有这样的效果也已经不错了。但是如果我们想达到更高的匹配度,我们应该尽量选择两张更为相似的图片。下面是我稍微修改后的代码:

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Aug 24 20:09:32 2018
  4. @author: lenovo
  5. """
  6. # -*- coding: utf-8 -*-
  7. """
  8. Created on Wed Aug 22 16:53:16 2018
  9. @author: lenovo
  10. """
  11. '''
  12. SURF算法
  13. '''
  14. import cv2
  15. '''1、加载图片'''
  16. img1 = cv2.imread('./image/match1.jpg')
  17. img1 = cv2.resize(img1,dsize=(600,400))
  18. gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
  19. img2 = cv2.imread('./image/match2.jpg')
  20. img2 = cv2.resize(img2,dsize=(600,400))
  21. gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
  22. image1 = gray1.copy()
  23. image2 = gray2.copy()
  24. '''2、提取特征点'''
  25. #创建一个SURF对象
  26. surf = cv2.xfeatures2d.SURF_create(10000)
  27. #SIFT对象会使用Hessian算法检测关键点,并且对每个关键点周围的区域计算特征向量。该函数返回关键点的信息和描述符
  28. keypoints1,descriptor1 = surf.detectAndCompute(image1,None)
  29. keypoints2,descriptor2 = surf.detectAndCompute(image2,None)
  30. print('descriptor1:',descriptor1.shape,'descriptor2',descriptor2.shape)
  31. #在图像上绘制关键点
  32. image1 = cv2.drawKeypoints(image=image1,keypoints = keypoints1,outImage=image1,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  33. image2 = cv2.drawKeypoints(image=image2,keypoints = keypoints2,outImage=image2,color=(255,0,255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  34. #显示图像
  35. cv2.imshow('surf_keypoints1',image1)
  36. cv2.imshow('surf_keypoints2',image2)
  37. cv2.waitKey(20)
  38. '''3、特征点匹配'''
  39. matcher = cv2.FlannBasedMatcher()
  40. matchePoints = matcher.match(descriptor1,descriptor2)
  41. print(type(matchePoints),len(matchePoints),matchePoints[0])
  42. #提取强匹配特征点
  43. minMatch = 1
  44. maxMatch = 0
  45. for i in range(len(matchePoints)):
  46. if minMatch > matchePoints[i].distance:
  47. minMatch = matchePoints[i].distance
  48. if maxMatch < matchePoints[i].distance:
  49. maxMatch = matchePoints[i].distance
  50. print('最佳匹配值是:',minMatch)
  51. print('最差匹配值是:',maxMatch)
  52. #获取排雷在前边的几个最优匹配结果
  53. goodMatchePoints = []
  54. for i in range(len(matchePoints)):
  55. if matchePoints[i].distance < minMatch + (maxMatch-minMatch)/4:
  56. goodMatchePoints.append(matchePoints[i])
  57. #绘制最优匹配点
  58. outImg = None
  59. outImg = cv2.drawMatches(img1,keypoints1,img2,keypoints2,goodMatchePoints,outImg,matchColor=(0,255,0),flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT)
  60. cv2.imshow('matche',outImg)
  61. cv2.waitKey(0)
  62. cv2.destroyAllWindows()

 

参考文章:

  • 图像识别基本算法之SURF
  • SURF算法
  • SURF算法与源码分析、上
  • SURF算法与源码分析、下
  • SURF原理及源码解析(C++)

转自:第十三节、SURF特征提取算法


http://chatgpt.dhexx.cn/article/k6mL6x47.shtml

相关文章

图像特征提取算法—HOG

图像特征提取算法—HOG 一 图像基本概念 1.1特征 边缘&#xff0c;角&#xff0c;区域。但不同的目的对应着的不同的特征&#xff0c;边缘特征&#xff0c;颜色特征&#xff0c;梯度方向分布等。 每个物体&#xff0c;我们总可以用一些词语或部件来描述它&#xff0c;比如人…

时域特征提取_EEG信号特征提取算法

点击上面"脑机接口社区"关注我们 更多技术干货第一时间送达 时域分析与频域分析 EEG信号特征提取就是以脑电信号作为源信号,确定各种参数并以此为向量组成表征信号特征的特征向量。 特征參数主要包括时域信号(如幅值)和频域信号(如频率)两大类,相应的特征提取方法也…

特征提取算法

特征提取 1、背景2、边界预处理Moore boundary tracing algorithmChain CodesFreeman Chain Codesslope chain codes (SCCs) minimum-perimeter polygon (MPP)signaturesskeletons 3、Region Feature Descriptors3.1 区域描述子和特征向量3.2 Topological Descriptors3.3 Textu…

深度学习之特征提取算法

目录 前言 二、LBP&#xff08;Local Binary Patterns,局部二值模式&#xff09; 三、HOG算法&#xff08;Histogram of Oriented Gradient, 方向梯度直方图&#xff09; 四、SIFT算子&#xff08;Scale-invariant feature transform ,尺度不变特征变换&#xff09; 五、H…

idea如何使用git关联远程仓库

1.git的配置 一般本地安装了git&#xff0c;idea会自动检索&#xff0c; 2.创建git本地仓库 一般以你要上传的项目为根目录 3.将文件提交至本地仓库 4.提交至远程仓库 点击VCS选择git点击push提交&#xff0c;第一次连接会让你输入远程仓库的地址。 我们先将github上的地…

git 将本地项目关联到远程仓库

原文链接&#xff1a;https://www.jianshu.com/p/2a8b4e627991 参考链接&#xff1a; https://blog.csdn.net/baidu_35085676/article/details/53456884 1.首先在项目目录下初始化本地仓库 git init 2.添加所有文件( . 表示所有) git add . 3.提交所有文件到本地仓库 git comm…

git创建本地仓库远程仓库,并关联。全过程

1.在网页中自己的github账号下&#xff0c;创建仓库project 2.在本机创建文件夹project。 进入文件夹project. (1) git init (2) git add README.md (3) git commit -m "first commit" (4) git branch -M master (5) git remote add origin https://github.co…

Git本地仓库与远程仓库关联

一、前提条件 1、本地一个仓库&#xff1a;本地仓库已经经过git init 初始化 2、远程一个仓库&#xff1a;已经存在了一个远程的仓库 3、GitHub已经添加了SSH Keys 二、建立远程与本地仓库的关联 本地仓库与远程仓库关联有两种方法&#xff0c;一种是通过IDE&#xff08;比…

使用git命令,本地仓库关联到远程仓库

本地仓库关联到远程&#xff1a; 创建成功会得到一个url地址和git全局设置的两行命令&#xff0c;下面从本地链接远程时会用到。 git config --global user.name "你的用户名" git config --global user.email "你的邮箱" 2、选择本地文件夹&#xff0c;在…

git关联两个远程仓库,一个仓库(github)拉取代码,另一个仓库(gitlab)推送代码

有这种情况&#xff0c;小伙伴们在github上下载的开源项目&#xff08;该开源项目还在继续开发维护&#xff09;&#xff0c;然后自己下载下来进行二次开发&#xff0c;然后又要把项目推送自己的gitlab私服上&#xff0c;这个时候不得不本地代码关联两个远程仓库。接下来我将一…

IDEA本地项目关联远程Git远程仓库

IDEA本地项目关联远程Git远程仓库 下面介绍几种方法&#xff1a; 一、代码 clone 到本地 这种方法是直接 clone 代码&#xff0c;这样不需要在手动关联仓库。 1、本地创建空白文件夹 2、右键 Git Bash Here 打开控制台 3、直接 clone 远程仓库的代码 git clone 远程地址&…

如何简单的在IDEA中关联git远程仓库

在IDEA中关联远程仓库有许多的方法&#xff0c;那么在这呢我教大家一种简单的方法。 那么在开始之前呢&#xff0c;需要大家在你自己的电脑上安装git&#xff0c;并且在Gitee上创建自己的仓库。 同时IDEA中需要下载Gitee的插件 那么我在这也创建好了一个测试仓库 点击黄色的…

关于GIT怎么将本地仓库和远程仓库进行关联

1 首先在本地创建一个和远程仓库一样的文件夹(直接在git的命令界面中就能创建&#xff0c;git命令界面貌似大部分的linux的命令都能用) 2 由于是一个空文件要让git认识需要初始化&#xff0c;初始化命令&#xff1a;git init ,会在在nihao中会出现一个.git的文件 3 初始化完成后…

本地项目关联远程 git 仓库

用了几年 git 来管理代码&#xff0c;除了常用的提交代码的一些指令&#xff0c;其他的每次用到都需要查一次资料&#xff0c;这样很麻烦。最近有一个新项目需要关联远程仓库&#xff0c;我自己也整理了一下。 安装 Git&#xff1a;官网 下面介绍几种方法&#xff1a; 一、代…

Git关联远程仓库和分支

背景 在我们开发过程中经常会将本地代码放到代码仓中。 解决方法有两种&#xff0c;这两种方法都有一个前提就是需要在gitLab中新建一个代码仓。 第一种方法就是先将这个新的远程代码仓拉取到本地&#xff0c;再将本地的代码移植到本地仓中&#xff0c;最后push到远程仓库中…

使用Git将本地仓库与远程仓库关联的三种方式

前提条件&#xff1a; Git已经配置完&#xff0c;能实现Push&#xff0c;Pull、Clone等操作 GitHub/Gitee已经添加了SSH Keys 没有配置好的参考这篇文章&#xff1a;是的是的 一、通过Clone远程仓库的方式 前提条件&#xff1a;创建好云端仓库即可 通过git clone指令clone到…

利用Git连接远程仓库(详细步骤)

利用Git连接远程仓库步骤及常见问题 1.先创建一个文件夹&#xff0c;名字为远程仓库的名称 2.在该文件目录下打开Git Bash 3.输入git init,进行初始化&#xff08;初次连接时&#xff09; 4.连接远程仓库&#xff08;初次连接是下一次进入该文件夹就不用了&#xff09; 输入…

Git- 连接远程仓库

如何使用Git 连接远程仓库呢&#xff1f;远程仓库->一般指的是代码托管平台。那就先来瞅瞅三个较熟悉的版本(代码)托管服务平台。 版本(代码)托管服务平台&#xff1a; 码云(gitee.com)&#xff1a;是开源中国社区团队推出的基于Git的快速的、免费的、稳定的在线代码托管平…

Git关联远程仓库

前面我们介绍的所有操作都是在本地仓库完成的&#xff0c;本文我们主要来看看如何和远程仓库进行交互&#xff0c;为了方便起见&#xff0c;这里远程仓库我们选择GitHub。 本文是Git系列的第五篇&#xff0c;了解前面的文章有助于更好的理解本文&#xff1a; 1.Git概述 2.Git基…

【git学习】本地关联远程仓库

目录 一、本地仓库关联远程仓库&#xff08;新建仓库&#xff09; 二、拉取远程分支到本地&#xff08;已有远程仓库&#xff09; 一、本地仓库关联远程仓库&#xff08;新建仓库&#xff09; 本地新建工程&#xff0c;然后关联远程git仓库并向远程仓库提交代码。 1、本地新建…