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.

补充
1.关于参数ksize和检测自由设置参数k,可参考博客【cornerHarris中的ksize和k是什么意思】--https://www.jb51.cc/python/533133.html
2.官方角点检测参考链接:https://docs.opencv.org/3.0-beta/modules/imgproc/doc/feature_detection.html?highlight=cv2.cornerharris#cv2.cornerHarris
3.goodFeaturesToTrack 函数参数详解https://blog.csdn.net/guduruyu/article/details/69537083 这个函数可以输入mask信息
4.对于有更精细检测需求的,可以使用cornerSubPix()来检测亚像素角点

对于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.👍

参考博客
1.OPENCV图像特征点检测与FAST算法https://www.cnblogs.com/dengxiaojun/p/5302778.html讲解该函数的算法及参数
2.KeyPoint类参考博客:https://blog.csdn.net/leonardohaig/article/details/81289648

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)

相关博客:
角点特征检测之三(FLANN匹配)https://blog.csdn.net/wsp_1138886114/article/details/90578810

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342