引自:基于Python和OpenCV实现图像的全景拼接_半濠春水的博客-CSDN博客_python opencv 图片合成

使用环境opencv4.5.4.58,python3.6,numpy1.19.3

有一个缺点就是现实的图框是乱码,但导出图片还是没问题的。

#ifdef OPENCV_ENABLE_NONFREE
#图像全景拼接import cv2       # 导入opencv包
import numpy as np      # 导入numpy包,图像处理中的矩阵运算需要用到# 检测图像的关键特征点
def sift_keypoints_detect(image):# 处理图像一般很少用到彩色信息,通常将图像转换为灰度图gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 获取图像特征sift-SIFT特征点,实例化对象siftsift = cv2.SIFT_create()# keypoints:特征点向量,向量内的每一个元素是一个KeyPoint对象,包含了特征点的各种属性信息(角度、关键特征点坐标等)# features:表示输出的sift特征向量,通常是128维的keypoints, features = sift.detectAndCompute(image, None)""" cv2.drawKeyPoints():在图像的关键特征点部位绘制一个小圆圈。如果传递标志flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,它将绘制一个大小为keypoint的圆圈并显示它的方向。这种方法同时显示图像的坐标,大小和方向,是最能显示特征的一种绘制方式。"""keypoints_image = cv2.drawKeypoints(gray_image, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)# 返回带关键特征点的图像、关键特征点和sift的特征向量return keypoints_image, keypoints, features# 使用KNN检测来自左右图像的SIFT特征进行匹配
def get_feature_point_ensemble(features_right, features_left):# 创建BFMatcher对象解决匹配bf = cv2.BFMatcher()# knnMatch()函数:返回每个特征点的最佳匹配k个匹配点# features_right为模板图,features_left为匹配图matches = bf.knnMatch(features_right, features_left, k=2)"""利用sorted()函数对matches对象进行升序(默认)操作,x:x[]字母可以随意修改,排序方式按照中括号[]里面的维度进行排序,[0]按照第一维排序,[2]按照第三维排序"""matches = sorted(matches, key=lambda x: x[0].distance / x[1].distance)# 建立列表good用于存储匹配的点集good = []for m, n in matches:# ratio的值越大,匹配的线条越密集,但错误匹配点也会增多ratio = 0.6if m.distance < ratio * n.distance:good.append(m)# 返回匹配的关键特征点集return good# 计算视角变换矩阵H,用H对右图进行变换并返回全景拼接图像
def Panorama_stitching(image_right, image_left):_, keypoints_right, features_right = sift_keypoints_detect(image_right)_, keypoints_left, features_left = sift_keypoints_detect(image_left)goodMatch = get_feature_point_ensemble(features_right, features_left)# 当筛选项的匹配对大于4对(因为homography单应性矩阵的计算需要至少四个点)时,计算视角变换矩阵if len(goodMatch) > 4:# 获取匹配对的点坐标Point_coordinates_right = np.float32([keypoints_right[m.queryIdx].pt for m in goodMatch]).reshape(-1, 1, 2)Point_coordinates_left = np.float32([keypoints_left[m.trainIdx].pt for m in goodMatch]).reshape(-1, 1, 2)# ransacReprojThreshold:将点对视为内点的最大允许重投影错误阈值(仅用于RANSAC和RHO方法时)# 若srcPoints和dstPoints是以像素为单位的,该参数通常设置在1到10的范围内ransacReprojThreshold = 4# cv2.findHomography():计算多个二维点对之间的最优单映射变换矩阵 H(3行x3列),使用最小均方误差或者RANSAC方法# 作用:利用基于RANSAC的鲁棒算法选择最优的四组配对点,再计算转换矩阵H(3*3)并返回,以便于反向投影错误率达到最小Homography, status = cv2.findHomography(Point_coordinates_right, Point_coordinates_left, cv2.RANSAC, ransacReprojThreshold)# cv2.warpPerspective():透视变换函数,用于解决cv22.warpAffine()不能处理视场和图像不平行的问题# 作用:就是对图像进行透视变换,可保持直线不变形,但是平行线可能不再平行Panorama = cv2.warpPerspective(image_right, Homography, (image_right.shape[1] + image_left.shape[1], image_right.shape[0]))cv2.imshow("扭曲变换后的右图", Panorama)cv2.waitKey(0)cv2.destroyAllWindows()# 将左图加入到变换后的右图像的左端即获得最终图像Panorama[0:image_left.shape[0], 0:image_left.shape[1]] = image_left# 返回全景拼接的图像return Panoramaif __name__ == '__main__':# 读取拼接图片image_left = cv2.imread("./allpic53.jpg")image_right = cv2.imread("./allpic52.jpg")# imageA = cv2.resize(imageA, dsize=None, fx=0.2, fy=0.2, interpolation=cv2.INTER_LINEAR)# imageB = cv2.resize(imageB, dsize=None, fx=0.2, fy=0.2, interpolation=cv2.INTER_LINEAR)"""通过调用cv2.resize()使用插值的方式来改变图像的尺寸,保证左右两张图像大小一致。cv2.resize()函数中的第二个形参dsize表示输出图像大小尺寸,当设置为0(None)时表示按fx与fy与原始图像大小相乘得到输出图像尺寸大小"""image_right = cv2.resize(image_right, None, fx=0.4, fy=0.24)image_left = cv2.resize(image_left, (image_right.shape[1], image_right.shape[0]))# 获取检测到关键特征点后的图像的相关参数keypoints_image_right, keypoints_right, features_right = sift_keypoints_detect(image_right)keypoints_image_left, keypoints_left, features_left = sift_keypoints_detect(image_left)# 利用np.hstack()函数同时将原图和绘有关键特征点的图像沿着竖直方向(水平顺序)堆叠起来cv2.imshow("左图关键特征点检测", np.hstack((image_left, keypoints_image_left)))# 一般在imshow后设置 waitKey(0) , 代表按任意键继续cv2.waitKey(0)# 删除先前建立的窗口cv2.destroyAllWindows()cv2.imshow("右图关键特征点检测", np.hstack((image_right, keypoints_image_right)))cv2.waitKey(0)cv2.destroyAllWindows()goodMatch = get_feature_point_ensemble(features_right, features_left)# cv2.drawMatches():在提取两幅图像特征之后,画出匹配点对连线# matchColor – 匹配的颜色(特征点和连线),若matchColor==Scalar::all(-1),颜色随机all_goodmatch_image = cv2.drawMatches(image_right, keypoints_right, image_left, keypoints_left, goodMatch, None, None, None, None, flags=2)cv2.imshow("所有匹配的SIFT关键特征点连线", all_goodmatch_image)cv2.waitKey(0)cv2.destroyAllWindows()# 把图片拼接成全景图并保存Panorama = Panorama_stitching(image_right, image_left)cv2.namedWindow("allpicres", cv2.WINDOW_AUTOSIZE)cv2.imshow("allpicres", Panorama)cv2.imwrite("./allpicres.jpg", Panorama)cv2.waitKey(0)cv2.destroyAllWindows()

使用时分清楚左右:

案例1:

image_left:

right:

res:

 案例2:

left:

right:

res:

另外,如果你想自拍照片试一下,我建议你平移这拍,别斜着拍,斜着拍就会只对齐一部分,像这样:

可以使用的图像全景拼接opencv相关推荐

  1. OpenCV C++案例实战十二《图像全景拼接》

    OpenCV C++案例实战十二<图像全景拼接> 前言 一.OpenCV Stitcher 1.功能源码 2.效果 二.图像全景拼接 1.特征检测 2.计算单应性矩阵 3.透视变换 4.图 ...

  2. ROS图像与OpenCV图像相互转换

    参考: https://blog.csdn.net/u013794793/article/details/79925491 使用cv_bridge将ROS图像转换为OpenCV图像,以及OpenCV图 ...

  3. 图像边缘检测--OpenCV之cvCanny函数

    图像边缘检测--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1 ...

  4. 计算机视觉(五)--图像全景拼接原理及实现

    一.图像全景拼接的原理 图像全景拼接就是将多张图片(两两间存在一定的重叠部分,可以是不同时间.不同视角或者不同传感器获得的)拼成一幅无缝的全景图或高分辨率图像的技术.也就是将两幅存在一定重合部分的图像 ...

  5. 图像金字塔与图像融合——OpenCv库

    图像金字塔与图像融合--OpenCv 内容来自博客~ OpenCV中图像特征描述算法(SIFT,SURF,ORB等)中涉及了图像金字塔的内容. 高斯金字塔 高斯金字塔是最基本的图像塔.首先将原图像作为 ...

  6. 计算机视觉第四次实验--基于RANSAC的图像全景拼接

    计算机视觉第四次实验–基于RANSAC的图像全景拼接 文章目录 计算机视觉第四次实验--基于RANSAC的图像全景拼接 一.明确图像拼接整体流程 二.APAP算法 三.算法流程: 四.最小割问题(最大 ...

  7. 图像去水印——opencv实现

    图像去水印--opencv实现 功能简介:通过拖动鼠标实现指定区域水印或是斑点的去除. 实现原理:利用opencv鼠标操作setMouseCallback函数框选(左上到右下)需要处理的区域,按下鼠标 ...

  8. 使用OpenCV进行图像全景拼接

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 图像拼接是计算机视觉中最成功的应用之一.如今,很难找到不包含此功能 ...

  9. opencv图像拼接_使用OpenCV进行图像全景拼接

    点击上方"AI小白学视觉",选择加"星标"或"置顶"重磅干货,第一时间送达 图像拼接是计算机视觉中最成功的应用之一.如今,很难找到不包含此功 ...

最新文章

  1. Git 常用命令,每条都很重要!
  2. Android之如何设置TextView中不同字段的字体颜色
  3. mysql 命令 g_MySQL命令行的几个用法
  4. 让一个文字在背景图片水平居中的方法
  5. 设计模式学习总结(一)——设计原则与UML统一建模语言
  6. iPhone 13系列或将涨价?业内人士:可能性不大,原因有这几点
  7. WebService可以远程调试调用
  8. 电机编码器调零步骤_什么是无刷直流电机换向的最有效方法?
  9. SourcesTree使用手册2:文件更新
  10. Leetcode 208:实现Trie(前缀树)
  11. ref改变样式 vue_我用React和Vue构建了同款应用,对比看看(2020版)
  12. protocol buffer安装及使用(非常详细)
  13. 在硅谷,人生的可能性不只有996
  14. getch方法_C++中getch函数使用时注意事项
  15. 修航片调卫片,不会PS的GISer不是一个好“美工“
  16. vs201x下正则表达式过滤中文
  17. three.js 05-06 之 CylinderGeometry 几何体
  18. 2020年全国工业固体废物、危险废物产生量、利用处置量及防治措施分析[图]
  19. 爬虫抓包问题全面分析
  20. [文献阅读]—一篇不错的低资源机器翻译综述(Neural Machine Translation for Low-Resource Languages: A Survey)

热门文章

  1. oracle12c导出转版本,ORA-39358:导出转储文件版本12.2.0与目标版本12.1.0.2.0不兼容
  2. 骨传导是表示啥、骨传导蓝牙立体声耳机
  3. 如何修复Office Word 2003里符号栏不能用?
  4. 华为5G模组MH5000-31在TX2上配置联网
  5. 专插本C语言入门第一天
  6. WMS与企业ERP/MES数据交换方法
  7. mysql max 获取另外值_来看看 MySQL 的这个 BUG,坑了多少人....
  8. windows软件-----办公效率提高
  9. Windows XP/2003系统全部命令
  10. USB2.0 HUB芯片方案-GL850G