用fw做网站页面,网站风格什么意思,wordpress指定ip登陆,青岛网站设计方案文章目录 #x1f9e1;#x1f9e1;实验流程#x1f9e1;#x1f9e1;SIFT算法原理总结#xff1a;实现SIFT特征检测和匹配通过RANSAC 实现图片拼接更换其他图片再次测试效果#xff08;依次进行SIFT特征提取、RANSAC 拼接#xff09; #x1f9e1;#x1f9e1;全部代… 文章目录 实验流程SIFT算法原理总结实现SIFT特征检测和匹配通过RANSAC 实现图片拼接更换其他图片再次测试效果依次进行SIFT特征提取、RANSAC 拼接 全部代码 实验流程 SIFT算法原理总结 1.创建尺度空间 高斯模糊去除噪声强调了图像的重要特征 根据原图创建不同比例的新图像 2.采用高斯差异DOG增强特征 如下对于某一比例的5张不同模糊程度的图像进行差分 3.关键点定位尺度不变性 找出局部最大值和最小值这里“局部”的含义它不仅包括该图像的周围像素像素所在的像素还包括八度中上一张和下一张图像的九个像素 这意味着将每个像素值与其他26个像素值进行比较以确定是否为局部最大值/最小值。例如在下图中从第一个八度获得了三个图像。将标记为x的像素与相邻像素绿色进行比较如果它是相邻像素中最高或最低的像素则将其选择为关键点 关键点的筛选 消除对比度低或非常靠近边缘的关键点 采用二阶泰勒展开消除对比度低或非常靠近边缘的关键点、采用二阶Hessian矩阵来识别具有高边缘度但对少量噪点无鲁棒性的关键点 4.关键点方向分配旋转不变性 对于每个关键点和其周围的像素都执行如下操作 根据梯度计算幅度和方向如下Gx9Gy14则 随后创建大小和方向的柱状图 5.生成描述符 已经通过3、4生成了具有尺度不变性和旋转不变性的关键点对于每个关键点使用相邻像素它们的方向和大小为该关键点生成一个唯一的指纹称为“描述符”。 6.关键点匹配 使用描述子之间的距离或相似度度量来匹配不同图像中的关键点通常采用最近邻或 k近邻方法来进行匹配。 在opencv中BFMatcher.match() 和BFMatcher.knnMatch()第一个返回最佳匹配第二个返回前k个最佳的匹配k值由用户指定。 实现SIFT特征检测和匹配 原始图像如下 截出两个图像分别截取前宽度的4/5和后4/5部分 画出关键点 SIFT匹配总共529个匹配按连线长度升序画出全部线 为方便观察画出按连线长度前100匹配的连线 将右侧图片旋转90度重复上述步骤 将右侧图片旋转15度并缩放到原图0.8倍重复上述步骤 通过RANSAC 实现图片拼接 右侧图片正放 拼接结果 右侧图片旋转90度 拼接结果 右侧图片旋转15度并缩放到0.8倍 拼接结果 更换其他图片再次测试效果依次进行SIFT特征提取、RANSAC 拼接 全部代码
import numpy as np
import cv2
from matplotlib import pyplot as plt
def cv_show(title,img):cv2.imshow(title, img)cv2.waitKey(0)cv2.destroyAllWindows()SIFT 图像特征连接 RANSAC拼接
def check_and_draw_KeyPoint(img1,img2):img1 cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)img2 cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)# Siftsift cv2.SIFT_create()kp1, des1 sift.detectAndCompute(img1,None)kp2, des2 sift.detectAndCompute(img2,None)# len(kp1), len(kp2)# Draw KeyPointimgShow1 cv2.drawKeypoints(img1,kp1,None,color(255,0,255)) #画出特征点并显示为红色圆圈imgShow2 cv2.drawKeypoints(img2,kp2,None,color(255,0,255)) #画出特征点并显示为红色圆圈cv_show(KeyPoint, np.hstack((imgShow1, imgShow2)))return img1,img2,kp1,kp2,des1,des2def match_KeyPoint(img1,img2,kp1,kp2,des1,des2,show_line_num100):# Feature Matchingbf cv2.BFMatcher(cv2.NORM_L1, crossCheckTrue)matches bf.match(des1,des2)matches sorted(matches, keylambda x:x.distance)# print(len(matches))imgShow cv2.drawMatches(img1, kp1, img2, kp2, matches[0:show_line_num], None, flags2)cv_show(Match,imgShow)def concat_Image(img1,img2,kp1,kp2,des1,des2):# 匹配特征并返回透视变换矩阵matcher cv2.BFMatcher()rawMatches matcher.knnMatch(des2, des1, 2)matches []for m in rawMatches:if len(m) 2 and m[0].distance m[1].distance * 0.75:matches.append((m[0].trainIdx, m[0].queryIdx))kp1 np.float32([kp.pt for kp in kp1])kp2 np.float32([kp.pt for kp in kp2])if len(matches) 4:ptsA np.float32([kp2[i] for (_, i) in matches])ptsB np.float32([kp1[i] for (i, _) in matches])(H, status) cv2.findHomography(ptsA, ptsB, cv2.RANSAC, 4.0)result cv2.warpPerspective(img2, H, (img2.shape[1] img1.shape[1], img2.shape[0]))result[0:img1.shape[0], 0:img1.shape[1]] img1cv_show(Concat Image,result)if __name____main__:# Read Original Imageimage cv2.imread(img/test2_Sift.jpg)height, width, _ image.shapeimage cv2.resize(image,(int(width*4/6),int(height*4/6))) # 图片有点宽缩放一下height, width, _ image.shape# 截取前4/5部分和后4/5部分img1 image[:, 0 : int(width * 4 / 5)]img2 image[:, int(width / 5) : width]img1 cv2.imread(img/test2_river1.png)img2 cv2.imread(img/test2_river2.png)# 可注释图像转变2img2旋转90度
# img2 cv2.rotate(img2, cv2.ROTATE_90_CLOCKWISE) # 旋转90度
# img2 cv2.resize(img2,(img2.shape[1], img1.shape[0]))# 可注释图像转变3img2旋转15度并且缩放到0.9倍,同时img1设置跟img2同样高度并且宽度按比例变换
# center(width/2,height/2)
# angle15
# scale0.8
# Mcv2.getRotationMatrix2D(center,angle,scale)
# img2cv2.warpAffine(img2,M,(int(width),int(1.1*height)))
# img1cv2.resize(img1,(int(img1.shape[1]*img2.shape[0]/img1.shape[0]), img2.shape[0]))cv_show(spilt, np.hstack((img1, img2))) #拼接显示原图# 调用自定义函数img1,img2,kp1,kp2,des1,des2check_and_draw_KeyPoint(img1,img2) # 检测并画出关键点match_KeyPoint(img1,img2,kp1,kp2,des1,des2, show_line_num100) # 连接关键点concat_Image(img1,img2,kp1,kp2,des1,des2) # 拼接图像