之前被要求做一个和图像拼接的项目,学习了图像拼接的原理和实践,在这里记录一下,包括基本的原理和用python写出的代码。
图像拼接,顾名思义,就是将两张或多张图像拼接一起,其关键就是找到两张图像的重叠部分,通过重叠部分实现拼接。
所以,关键可以概括为两部分,一是如何找到重叠部分,在图像处理中称为特征点的提取和匹配;二是根据重叠部分来叠加图像,将右图根据重叠部分覆盖到左图上。
拼接的步骤
1.对每幅图做特征提取,再对两幅图做特征匹配。
2.图像配准及误匹配点的去除,即根据匹配的特征点找出重叠部分的对应坐标,并求出对应坐标转换的矩阵homography。
3.根据转换矩阵将右图拷贝到左图的指定位置上。
4.对重叠的边界做特殊处理,如平滑处理、去裂缝处理、过渡等。
特征点提取算法:
(1)SIFT算法:尺度不变特征转换
(2)SURF算法:加速稳健特征
(3)ORB算法
它们都具有尺度不变的特征,即两幅图像中不同尺度的同一物体点,两个尺度因子之间的比率应等同与图像尺度的比率。
特征点即为关键点,一般为角点、边缘点、暗区域的亮点、亮区域的暗点、局部极值点。
SIFT为最基础的算法,SURF和ORB都是在SIFT的基础进行修改,提升了运算的速度。
特征点匹配算法:
(1)BF算法
(2)FLANN算法
使用python和opencv库函数实现
ORB算法:
# ORB
def orb_extract(img1, img2):
orb = cv2.ORB_create(10)
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# BF
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
key_number1 = len(kp1)
key_number2 = len(kp2)
match_number = len(matches)
max_number = np.maximum(key_number1, key_number2)
score = float(float(match_number) / float(max_number))
img_orb = cv2.drawMatches(img1, kp1, img2, kp2, matches[:50], img2, flags=2)
return img_orb, score
SURF算法:
# SURF
def surf_extract(img1, img2):
surf = cv2.xfeatures2d.SURF_create(100)
# surf.setHessianThreshold(10000)
# SIFT:cv2.xfeatures2d.SIFT_create()
# SURF:cv2.xfeatures2d.SURF_create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright)
key1, describe1 = surf.detectAndCompute(img1, None)
img11 = cv2.drawKeypoints(img1, key1, img1, color=(255, 0, 0))
key2, describe2 = surf.detectAndCompute(img2, None)
img12 = cv2.drawKeypoints(img2, key2, img2, color=(255, 0, 0))
# FLANN
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
match = flann.knnMatch(describe1, describe2, k=2)
key_number1 = len(key1