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()

image.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()


image.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()


image.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()


image.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()

image.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()

image.png

颜色越深代表特征越重要


最后补充一下图像金字塔


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


————————————————

版权声明:本文为CSDN博主「今晚打佬虎」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u014281392/article/details/79693350


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年3月    »
123
45678910
11121314151617
18192021222324
25262728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864