python十角星_OpenCV-Python系列十一:特征检测(1)--角点检测

角点特征常常是图像中独特的存在,比如你在玩拼图游戏时,首先肯定会去找一些独一无二的匹配项,比如人像的眼睛,嘴巴,这些特征你很容易判断哪些碎片应该拼凑在一起,而相比之下,那些比较常见的特征你需要最后多次调整才能找到对的位置。角点特征就是这样较独特的存在,下图中矩形的右上角点区域,无论你往哪个方向移动,图像的信息都会发生变化,而边缘则沿某一个方向移动时不会变化,至于矩形内部区域,则无论哪个方向移动,图像信息没有变化[引用自官方教程]。

角点特征那么,在OpenCV里,有哪些能帮你解决问题的呢?

本文内容涉及以下内容(参考OpenCV3 计算机视觉第6章)

Harris角点检测

Shi-Tomasi角点检测(Harris的修改版)

FAST角点检测

有了特征点,怎么用呢?你可以比对不同图像的特征信息,进行目标检测、图像拼接等。在OpenCV中,可以通过下面的算子来进行特征匹配:

Brute-Force匹配法,也称暴力匹配法

基于FLANN的匹配法

1.使用Harris以及Shi-Tomasi算子获取角点

Harris | Shi-Tomasi角点

注:这里采用Shi-Tomasi仅保留最好的12个角点信息(匹配比较好),而harris输出了全部角点,圆圈颜色深表示该处检测到的次数多。

import cv2

import numpy as np

import time

img = cv2.imread('approx_star.png', -1)

img_copy = img.copy()

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

gaussian_img = cv2.GaussianBlur(gray_img,(3, 3),0)

# 输入图像必须是float32

float_img = np.float32(gaussian_img)

# Harris角点检测

## src: 输入图像

## blockSize:邻域大小

## ksize:Sobel算子中的核大小

## k :Harris检测参数,经验范围:[0.04, 0.06],值越大,假角点越少,不过可能会漏检

start_time = time.time()

dst = cv2.cornerHarris(float_img, 4, 3, 0.08)

end_time = time.time()

print('Harris Detection used :%s ms.' % ((end_time - start_time) * 1000))

dot_locs = np.where(dst > (0.01 * dst.max()))

for loc in zip(*dot_locs[::-1]):

cv2.circle(img, loc, 5, (25, 25, 255), 1)

# Shi-Tomasi方法检测

## src: 输入图像

## maxCorners:输出的角点数目,可以帮助你找到最佳的maxCorners个角点,会将角点进行排序

## qualityLevel:检测质量水平系数,经验值[0.01, 0.1]

## minDistance:最小的角点距离,小于该距离的角点会被忽视

start_time = time.time()

corners = cv2.goodFeaturesToTrack(gaussian_img, 12, 0.01, 10)

end_time = time.time()

print('goodFeaturesToTrack Detection used :%s ms.' % ((end_time - start_time) * 1000))

corners = np.int64(corners)

for corner in corners:

x, y = corner.flatten()

cv2.circle(img_copy, (x, y), 5, (255, 25, 255), 3)

cv2.imshow('harris_corners', img)

cv2.imshow('shi-tomasi_corners', img_copy)

cv2.waitKey(0)

cv2.destroyAllWindows()

# 耗时情况:

# Harris Detection used :5.984783172607422 ms.

# goodFeaturesToTrack Detection used :9.972572326660156 ms.

对于FAST检测角点的基本使用方法如下:

# 创建检测器,大多数情况下阈值设置较大,太低会造成大量的假特征点

# 选择非极大值抑制会使得特征点会少一些,避免一些假特征点

# type可选择FAST_FEATURE_DETECTOR_TYPE_9_16,在像素周围取16个点,当9个满足条件,就是特征点,除此之外,可选择7_12, 5_8

fast=cv2.FastFeatureDetector_create(threshold = 20, nonmaxSuppression=False,

type=cv2.FAST_FEATURE_DETECTOR_TYPE_9_16)

# 返回的kp为keypoint类,你可以使用kp[0].pt获取第一个特征点的坐标信息

# detect第二个参数为特征点,第三个参数为mask

kp = fast.detect(gray_img, None)

# 耗时情况

# FAST Detection used :0.9963512420654297 ms.👍

2.特征点匹配

你可以用特征点用在两幅图的信息比对上,这一点在图像拼接中尤为重要,至于说用特征进行目标检测,比如《OpenCV3 计算机视觉》中有将特征信息作为纹身信息的比对.不过,当你的环境特征信息量比较多(比如风景)的时候,匹配出错的概率非常大.

ORB算法特征匹配

# ORB特征点匹配

import cv2

import numpy as np

import time

# 特征图像

img = cv2.imread('fuji_features1.png',-1)

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 待匹配图像

img1 = cv2.imread('fuji_feature.jpg',-1)

gray_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

start_time = time.time()

orb = cv2.ORB_create()

kp1, des1 = orb.detectAndCompute(gray_img, None)

kp2, des2 = orb.detectAndCompute(gray_img1, None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)

matches = bf.match(des1, des2)

end_time = time.time()

print('ORB Detect Features and BFMatch used :%s ms.' % ((end_time - start_time) * 1000))

# good_matches = []

# for m, n in matches:

# if m.distance < 0.75 * n.distance:

# good_matches.append([m])

# 按照特征点距离进行排序,距离越小约好

# 参考博客:https://blog.csdn.net/u013000248/article/details/85325136

matches = sorted(matches, key = lambda x : x.distance)

img2 = cv2.drawMatches(img, kp1, img1, kp2, matches[:40], np.array([]), flags = 2)

cv2.imshow('ORB_corners', img2)

cv2.waitKey(0)

cv2.destroyAllWindows()

2.1 ORB 特征 + FLANN匹配

需要注意一下,ORB 进行特征提取的descriptor格式需要转换下,否则是无法进行FLANN匹配

FLANN_INDEX_KDTREE = 1

indexParams = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)

searchParams = dict(check = 50)

flann = cv2.FlannBasedMatcher(indexParams, searchParams)

# 转为np.float32

matches = flann.knnMatch(np.float32(des1), np.float32(des2), k = 2)

关于opencv-python的特征检测及匹配部分相关内容非常多,由于目前暂未涉及相关应用,如果你的应用中涉及相关内容,有问题的话请在评论区留言.Have Fun With OpenCV-Python, 下期见。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值