本文基于opencv官方文档,是本人的学习笔记。版本是在linux下的opencv4.2.0,全部程序调通可运行,无bug。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

filename = 'image1.jpg'
img = cv.imread(filename)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray, 2, 3, 0.04)
# result用于标记角点,并不重要
dst = cv.dilate(dst, None)
# 最佳值的阈值,它可能因图像而异。
img[dst > 0.01 * dst.max()] = [0, 0, 255]
cv.imshow('dst', img)
if cv.waitKey(0) & 0xff==27:
    cv.destroyAllWindows()

filename = 'image1.jpg'
img = cv.imread(filename)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 寻找哈里斯角
gray = np.float32(gray)
dst = cv.cornerHarris(gray, 2, 3, 0.04)
dst = cv.dilate(dst, None)
ret, dst = cv.threshold(dst, 0.01 * dst.max(), 255, 0)
dst = np.uint8(dst)
# 寻找质心
ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst)
# 定义停止和完善拐角的条件
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv.cornerSubPix(gray, np.float32(centroids), (5, 5), (-1, -1), criteria)
# 绘制
res = np.hstack((centroids, corners))
res = np.int0(res)
img[res[:, 1], res[:, 0]] = [0, 0, 255]
img[res[:, 3], res[:, 2]] = [0, 255, 0]
cv.imwrite('subpixel5.png', img)

# Shi-tomas拐角检测器和益于跟踪的特征
img = cv.imread('image1.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
corners = cv.goodFeaturesToTrack(gray, 25, 0.01, 10)
corners = np.int0(corners)
for i in corners:
    x, y = i.ravel()
    cv.circle(img, (x, y), 3, 255, -1)
plt.imshow(img), plt.show()

# SIFT(尺度不变特征变换)
# 下面的方法已经在最新的opencv中不能使用了,因为SIFT申请了专利
# 貌似opencv3.4之前的版本可用(本人未尝试)
# img = cv.imread('hui.jpg')
# gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# sift = cv.xfeatures2d.SIFT_create()
# kp = sift.detect(gray,None)
# img=cv.drawKeypoints(gray,kp,img)
# img=cv.drawKeypoints(gray,kp,img,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# cv.imwrite('sift_keypoints.jpg',img)

# SURF特征检测方法
# 同上 但是真的使用的话是有办法的,详情自行百度
# img = cv.imread('fly.png',0)
# # 创建SURF对象。你可以在此处或以后指定参数。
# # 这里设置海森矩阵的阈值为400
# surf = cv.xfeatures2d.SURF_create(400)
# # 直接查找关键点和描述符
# kp, des = surf.detectAndCompute(img,None)
# print(len(kp))
# img2 = cv.drawKeypoints(img,kp,None,(255,0,0),4)
# plt.imshow(img2),plt.show()

# 用于角检测的FAST算法
img = cv.imread('image1.jpg', 0)
# 用默认值初始化FAST对象
fast = cv.FastFeatureDetector_create()
# 寻找并绘制关键点
kp = fast.detect(img, None)
img2 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))
# 打印所有默认参数
print("Threshold: {}".format(fast.getThreshold()))
print("nonmaxSuppression:{}".format(fast.getNonmaxSuppression()))
print("neighborhood: {}".format(fast.getType()))
print("Total Keypoints with nonmaxSuppression: {}".format(len(kp)))
cv.imwrite('fast_true.png', img2)
# 关闭非极大抑制
fast.setNonmaxSuppression(0)
kp = fast.detect(img, None)
print("Total Keypoints without nonmaxSuppression: {}".format(len(kp)))
img3 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))
cv.imshow('image.', img2)
cv.imshow('image', img3)
cv.waitKey(0)
cv.imwrite('fast_false.png', img3)

# BRIEF 二进制的鲁棒独立基本特征
img = cv.imread('image1.jpg', 0)
# 初始化FAST检测器
star = cv.xfeatures2d.StarDetector_create()
# 初始化BRIEF提取器
brief = cv.xfeatures2d.BriefDescriptorExtractor_create()
# 找到STAR的关键点
kp = star.detect(img, None)
# 计算BRIEF的描述符
kp, des = brief.compute(img, kp)
print(brief.descriptorSize())
print(des.shape)

# ORB特征检测
img = cv.imread('image1.jpg', 0)
# 初始化ORB检测器
orb = cv.ORB_create()
# 用ORB寻找关键点
kp = orb.detect(img, None)
# 用ORB计算描述符
kp, des = orb.compute(img, kp)
# 仅绘制关键点的位置,而不绘制大小和方向
img2 = cv.drawKeypoints(img, kp, None, color=(0, 255, 0), flags=0)
plt.imshow(img2), plt.show()