什么是角点,角点有什么作用?
如上图,红色方框代表的即这张图片的角点。对于红色方框而言,无论方框沿任意方向移动都会导致方框内信息变化 ,而对于绿色方框而言,若两个方框间彼此的位置变化则不会引起大量的图像信息发生改变。对于某一区域而言,若像红色方框内数据一般,会随着矩阵的变化而引起图像数据变化的图像区域就叫做这张图像的角点。
对于同一物品的两张不同拍摄位置而言,我们可以根据角点 将两张图片 关联起来。
opencv-python 中 有着各种各样的角点检测函数,此篇文章中我们讲解常用的 SIFT 特征检测器。
SIFT (中文简译:与缩放无关的特征转换)
实验图像:
实验开始:
图像准备
import cv2
# 用于显示图像
def cv_show(img, title='title'):
cv2.imshow(title, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 读取图像
img_org_small = cv2.imread("small.jpg")
img_org_big = cv2.imread("big.jpg")
# 图像过大,改变图像大小
resize_c = 0.4
resize_c2 = 0.3
img_small = cv2.resize(img_org_small, (0, 0), fx=resize_c2, fy=resize_c2)
img_big = cv2.resize(img_org_big, (0, 0), fx=resize_c, fy=resize_c)
# 将图像转为灰度
img_small_gray = cv2.cvtColor(img_small, cv2.COLOR_BGR2GRAY)
img_big_gray = cv2.cvtColor(img_big, cv2.COLOR_BGR2GRAY)
使用SIFT获取角点的keypoint与描述子
# 创建SIFT对象
sift = cv2.SIFT_create()
# 获取特征点和描述子
kp_small, des_small = sift.detectAndCompute(img_small_gray, None)
kp_big, des_big = sift.detectAndCompute(img_big_gray, None)
keypoint信息
描述子信息
使用FLANN进行特征匹配
# 创建flann对象
index_params = dict(algorithm=1, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
# 特征匹配
res = flann.knnMatch(des_small, des_big,k=2)
FLANN使用设置的参数algorithm选择的是欧氏距离,因此我们将距离差大于一般的去除掉,保存距离小于一般的,此处的距离可以理解为相似度,约接近0代表约相近。
# 去除距离远的
asd = [list(map(lambda x:x[0], filter(lambda x: x[0].distance < x[1].distance*0.25,res)))]
(此处使用了map结合filter的方法紧凑了代码,不会的读者可以参考我的另一篇文章)
python 中 map、 filter 方法的区别与使用
将两张图像的角点进行关联可视化
# 绘制关键点
img_draw = cv2.drawMatchesKnn(img_small, kp_small, img_big, kp_big, asd, None,)
cv_show(img_draw)
运行结果
此时,我们及可根据找到的相似角点进行下一步处理