OpenCV3.0-图像特征检测

使用opencv的一些内置的算法来实现对图像特征的检测 
从图像中提取的到的特征可以用来进行图像的匹配和检索
常用的图像特征检测算法
Harris:检测角点
SIFT:检测斑点
SURF:检测斑点
FAST:检测角点
BRIEF:检测斑点

什么是图像特征?
  图像特征就是图像中最具有独特性和具有区别性的图像区域.在图像中特征区域主要分布在角点,高密度区域,边缘(边缘可以将图像分成多个区域),斑点(与周围像素差别很大的区域)

cornerHarrir()角点的检测

import cv2
import numpy as np
import matplotlib.pyplot as plt
img1 = cv2.imread('data/aero3.jpg',cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
# 第二个参数:特征标记点的大小
# 第三个参数:特征检测敏感度大小,介于3-31之间的奇数
dst = cv2.cornerHarris(gray, 3, 23, 0.04)
# 特征点标记为红色
img1[dst>0.01*dst.max()] = [255,0,0]

Harri可以很好的检测角点,而且在旋转的条件下,也可以很好的检测,这跟角点的特性有关.

plt.figure(figsize=(12,7))
plt.imshow(img1)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SU75vl8C-1680055549449)(output_6_0.png)]这里写图片描述

DOG和SIFT进行特征提取

在某些情况下对图像进行缩放后,角点信息可能会丢失,这时候Harri便不能检测到所有的角点,SIFT(scale-invariant feature transform)刚好克服了这个问题,对图像特征的检测,尽量不受图像尺寸变化的影响.SIFT并不直接检测关键点,
关键点的检测是由DOG(Difference of Gaussians)检测的.SIFT仅通过特征向量来描述特征点周围的像素情况.
DOG是通过不同的高斯滤波器对同一张图像进行处理,来得到关键点的.

img2 = cv2.imread('data/aero3.jpg')
gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray,None)
# 将关键点标记的图片上
img2 = cv2.drawKeypoints(image=img2, outImage=img2, keypoints=keypoints,
                        flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                        color=(255,0,0))
plt.figure(figsize=(12,7))
plt.imshow(img2)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SwTE2ARt-1680055549450)(output_9_0.png)]这里写图片描述

img3 = cv2.imread('data/building.jpg')
gray = cv2.cvtColor(img3, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
# 检测和计算,返回关键点和关键点的描述向量
keypoints, descriptor = sift.detectAndCompute(gray,None)
# 将关键点标记的图片上
img3 = cv2.drawKeypoints(image=img3, outImage=img3, keypoints=keypoints,
                        flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                        color=(255,0,0))
plt.figure(figsize=(12,7))
plt.imshow(img3)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQ24AZFw-1680055549450)(output_10_0.png)]这里写图片描述

Hessian算法和SURF来提取和检测特征

SURF来提取特征,Hessian算法来检测关键点,SIFT和SURF都在xfeatures模块下面(这两个算法受专利保护)

img4 = cv2.imread('data/building.jpg')
gray = cv2.cvtColor(img4, cv2.COLOR_BGR2GRAY)
# 传递一个阈值,值越高识别的特征就越少
sift = cv2.xfeatures2d.SURF_create(8000)
keypoints, descriptor = sift.detectAndCompute(gray,None)
# 将关键点标记的图片上
# flags =4 等价于cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
img4 = cv2.drawKeypoints(image=img4, outImage=img4, keypoints=keypoints,
                        flags = 4, color=(255,0,0))
plt.figure(figsize=(12,7))
plt.imshow(img4)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jYkdjQuH-1680055549451)(output_13_0.png)]这里写图片描述

基于ORB的特征检测

ORB是基于FAST关键点检测技术和BRIEF描述符结合的特征检测技术.
   **FAST(Features from Accelerated Segment Test)**算法会在像素周围绘制一个圆,圆内包含16个像素,FAST算法是将圆内的像素分别与加上一个阈值的圆心像素作比较,若圈内出现连续的几个像素比加上一个阈值的像素还亮或是暗,则可认为圆心是角点.FAST是一个很有效率的检测算法,但是需要确定阈值参数来检测角点.
   **BRIEF(Binary Robust Independent Elementary Features)**在OpenCV中主要是通过detectAndCompute()来实现,这个函数包含两个部分,检测和计算,同时也返回两个结果.一个是检测到的关键点,一个是描述符.SIFT和SURF也是这样.关键点的描述符包含了图像的关键信息,可看作是图像的另一种表现形式,在比较两个图像的时候可以通过比较两个图像的特征描述来实现.也可以用来做图像特征的匹配.

# 参数对照
# IMREAD_ANYCOLOR = 4
# IMREAD_ANYDEPTH = 2
# IMREAD_COLOR = 1
# IMREAD_GRAYSCALE = 0
# IMREAD_LOAD_GOAL = 8
# IMREAD_UNCHANGED = -1
img5 = cv2.imread('data/building.jpg',cv2.IMREAD_GRAYSCALE)
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img5, None)
img4 = cv2.drawKeypoints(image=img5, outImage=img5, keypoints=keypoints,
                        flags = 4, color=(255,0,0))
plt.figure(figsize=(12,7))
plt.imshow(img5)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8SJCvKF-1680055549451)(output_17_0.png)]这里写图片描述

最后详细说下特征提取的keypoints和descript包含哪些些信息

以最近的这幅图片为例,它是用ORB算法做的特征检测,先看下得到的关键点和描述符的数量

# 上图中关键点和描述符的数量
len(kp1),len(des1)
(500, 500)

特征点

特征点的数量和描述符的数量是相等的,他们是一一对应的,他们都存放在一个列表对象当中,每个关键点包含6个属性,分别是:
pt : 关键点在图像中的坐标信息
size : 关键点所在区域的直径信息
angle : 关键点的方向信息
response : 关键点的强度信息
octave : 是关于该特征来自图像金字塔的层级信息
calss_id : 特征id

# 第一个关键点的属性信息
b = kp1[0]
b.angle, b.class_id, b.octave, b.pt, b.response, b.size
(203.91419982910156, -1, 0, (762.0, 272.0), 0.0018553065601736307, 31.0)

描述符:一个长度为32的特征向量

# 第一个关键点的描述符
a = des1[0]
a
array([137, 159, 147, 191, 253, 141, 182, 247, 223,  14,  80,  86, 172,
       249,  33, 205, 207, 123, 134,   3,  34, 254,  74, 255, 173, 215,
        62,  10, 146,  88, 161, 139], dtype=uint8)
a[::-1]-30
array([109, 131,  58, 116, 236,  32, 185, 143, 225,  44, 224,   4, 229,
       104,  93, 177, 175,   3, 219, 142,  56,  50, 240, 193, 217, 152,
       111, 223, 161, 117, 129, 107], dtype=uint8)

可视化特征的坐标信息和特征强度

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# points存储每个关键点的坐标和层级信息和特征强度
points = np.zeros((500,4))
points[0] = (1,2,3,4)
for index, kpoint in enumerate(kp1):
    points[index] = (kpoint.pt[0],kpoint.pt[1], kpoint.octave, kpoint.response)
fig = plt.figure(figsize=(15,8))
ax = fig.gca(projection = '3d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z layer')
ax.set_title('Visualization keyPoints')
# 图像中的坐标是从左上角开始的,所以600-
ax.scatter(points[:,0], 600-points[:,1], points[:,2], c=points[:,3],s=30)
plt.show()

这里写图片描述

颜色越深代表特征越重要

最后补充一下图像金字塔

图像金字塔其实是图像的不同尺寸的多种表示,按照尺寸的大小排列,层数越高尺寸越小,这样做的目的是为了能够解决不同尺度下的目标检测问题,待检测的目标图像尺寸大小不同,在做特征匹配的时候,就需要多种不同大小的图像,对输入图像的不同尺寸进行特征检测.

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SIFT(尺度不变特征转换)是一种图像特征提取算法,而RANSAC(随机抽样一致性)是一种用于剔除误匹配点的算法。下面是关于如何在OpenCV 3.0中实现这两种算法的简要步骤。 首先,打开一个图像并加载其所需的库: ``` import cv2 import numpy as np ``` 然后,我们可以从图像中提取SIFT特征: ``` # 加载图像 img = cv2.imread('image.jpg',0) # 创建SIFT对象 sift = cv2.xfeatures2d.SIFT_create() # 检测并计算SIFT特征 keypoints, descriptors = sift.detectAndCompute(img, None) ``` 接下来,我们可以使用RANSAC算法来剔除误匹配点: ``` # 创建FLANN匹配器对象 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) # 在两幅图像之间匹配特征点 matches = flann.knnMatch(descriptors1, descriptors2, k=2) # 进行RANSAC过滤 good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) # 绘制匹配结果 result = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, None, flags=2) cv2.imshow('Matches', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,我们首先创建了一个FLANN(快速最近邻搜索)匹配器对象,然后使用`knnMatch`函数在两幅图像之间进行特征点的匹配。最后,我们使用RANSAC算法对匹配点进行过滤,并将结果绘制出来。 以上是在OpenCV 3.0中实现SIFT特征提取和RANSAC误匹配点剔除的简要步骤。实际操作中还可以进行更详细的参数设置和优化,以便得到更好的匹配结果。 ### 回答2: OpenCV 3.0 是一个非常强大的计算机视觉库,它提供了许多功能来处理图像处理和计算机视觉任务。其中包括使用SIFT算法进行特征提取和使用RANSAC算法进行误匹配点的剔除。 首先,SIFT(尺度不变特征变换)是一种用于在图像检测和描述关键点的算法。在OpenCV 3.0中,你可以使用`cv2.xfeatures2d.SIFT_create()`来创建一个SIFT对象。然后,你可以使用`detectAndCompute()`方法来检测并计算图像的关键点和特征描述符。通过调用这个方法,你将得到检测到的关键点和对应的特征描述符。 接下来,我们可以使用RANSAC(随机样本一致性)算法来剔除误匹配点。RANSAC算法能够通过随机选择样本子集并估计模型参数来寻找数据中的局内点。在OpenCV 3.0中,你可以使用`cv2.RANSAC`作为参数来创建一个RANSAC对象。然后,你可以使用`findHomography()`方法来计算通过RANSAC算法筛选后的匹配点之间的透视变换矩阵。这个矩阵可以用来剔除误匹配点。 总结一下,OpenCV 3.0可以通过`cv2.xfeatures2d.SIFT_create()`方法进行SIFT特征提取,并使用RANSAC算法来剔除误匹配点。这两个功能都是非常有用的计算机视觉任务,能够帮助我们更好地处理和分析图像。 ### 回答3: 在OpenCV 3.0中,可以使用SIFT算法进行图像特征提取,并采用RANSAC算法剔除误匹配点。 SIFT(Scale-Invariant Feature Transform)特征提取算法是一种基于尺度空间的特征提取方法,它可以提取图像中的稳定特征点和其对应的描述子。在OpenCV中,可以使用sift.detectAndCompute()函数来提取图像的SIFT特征点和描述子。 RANSAC(Random Sample Consensus)算法是一种鲁棒的参数估计算法,它可以从一组数据中剔除异常点,从而得到准确的模型参数。在特征匹配中,可以使用RANSAC算法来剔除误匹配点,以提高匹配的准确性。 具体实现的步骤如下: 1. 导入OpenCV和Numpy库,并读取需要进行特征匹配的两幅图像。 ```python import cv2 import numpy as np img1 = cv2.imread('image1.jpg', 0) img2 = cv2.imread('image2.jpg', 0) ``` 2. 创建SIFT对象,并使用sift.detectAndCompute()函数提取图像的SIFT特征点和描述子。 ```python sift = cv2.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) ``` 3. 使用FLANN匹配器对两幅图像的描述子进行匹配。 ```python FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) ``` 4. 运用RANSAC算法剔除误匹配点。 ```python good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) ``` 通过以上步骤,我们可以得到经过RANSAC算法筛选后的匹配点,并且可以通过M矩阵获取图像的对应关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值