文章目录

  • 前言
  • 完整源码
    • 下载链接:[https://download.csdn.net/download/DeepLearning_/87290571](https://download.csdn.net/download/DeepLearning_/87290571)
  • 一、效果展示
    • 1.山体拼接效果(3张原图)
    • 2.建筑拼接效果(5张原图)
    • 3.房间图像拼接(3张原图)
  • 二、使用步骤
    • 1.引入库
    • 2.主体函数
  • 总结

前言

图像拼接是将同一场景的多个重叠图像拼接成较大的图像的一种方法,在医学成像、计算机视觉、卫星数据、军事目标自动识别等领域应用广泛。图像拼接的输出是两个输入图像的并集
所谓图像拼接就是将两张有共同拍摄区域的图像无缝拼接在一起。这种应用可应用于车站的动态检测、商城的人流检测、十字路口的交通检测等,给人以全景图像,告别目前的监控墙或视频区域显示的时代,减轻工作人员“眼”的压力。本文介绍python+opencv实现多张图片(3张+)拼接任务。


提示:以下是本篇文章正文内容,下面案例可供参考

完整源码

下载链接:https://download.csdn.net/download/DeepLearning_/87290571

一、效果展示

1.山体拼接效果(3张原图)

原始图片



拼接后效果:

2.建筑拼接效果(5张原图)

原始图片





拼接后效果:

3.房间图像拼接(3张原图)

原始图片


拼接后效果:

二、使用步骤

1.引入库

代码如下(示例):

import numpy as np
import cv2
import sys
from matchers import matchers
import time

2.主体函数

代码如下(示例):

class Stitch:def __init__(self, args):self.path = argsfp = open(self.path, 'r')filenames = [each.rstrip('\r\n') for each in  fp.readlines()]print filenamesself.images = [cv2.resize(cv2.imread(each),(480, 320)) for each in filenames]self.count = len(self.images)self.left_list, self.right_list, self.center_im = [], [],Noneself.matcher_obj = matchers()self.prepare_lists()def prepare_lists(self):print "Number of images : %d"%self.countself.centerIdx = self.count/2 print "Center index image : %d"%self.centerIdxself.center_im = self.images[int(self.centerIdx)]for i in range(self.count):if(i<=self.centerIdx):self.left_list.append(self.images[i])else:self.right_list.append(self.images[i])print "Image lists prepared"def leftshift(self):# self.left_list = reversed(self.left_list)a = self.left_list[0]for b in self.left_list[1:]:H = self.matcher_obj.match(a, b, 'left')print "Homography is : ", Hxh = np.linalg.inv(H)print "Inverse Homography :", xhds = np.dot(xh, np.array([a.shape[1], a.shape[0], 1]));ds = ds/ds[-1]print "final ds=>", dsf1 = np.dot(xh, np.array([0,0,1]))f1 = f1/f1[-1]xh[0][-1] += abs(f1[0])xh[1][-1] += abs(f1[1])ds = np.dot(xh, np.array([a.shape[1], a.shape[0], 1]))offsety = abs(int(f1[1]))offsetx = abs(int(f1[0]))dsize = (int(ds[0])+offsetx, int(ds[1]) + offsety)print "image dsize =>", dsizetmp = cv2.warpPerspective(a, xh, dsize)# cv2.imshow("warped", tmp)# cv2.waitKey()tmp[offsety:b.shape[0]+offsety, offsetx:b.shape[1]+offsetx] = ba = tmpself.leftImage = tmpdef rightshift(self):for each in self.right_list:H = self.matcher_obj.match(self.leftImage, each, 'right')print "Homography :", Htxyz = np.dot(H, np.array([each.shape[1], each.shape[0], 1]))txyz = txyz/txyz[-1]dsize = (int(txyz[0])+self.leftImage.shape[1], int(txyz[1])+self.leftImage.shape[0])tmp = cv2.warpPerspective(each, H, dsize)cv2.imshow("tp", tmp)cv2.waitKey()# tmp[:self.leftImage.shape[0], :self.leftImage.shape[1]]=self.leftImagetmp = self.mix_and_match(self.leftImage, tmp)print "tmp shape",tmp.shapeprint "self.leftimage shape=", self.leftImage.shapeself.leftImage = tmp# self.showImage('left')def mix_and_match(self, leftImage, warpedImage):i1y, i1x = leftImage.shape[:2]i2y, i2x = warpedImage.shape[:2]print leftImage[-1,-1]t = time.time()black_l = np.where(leftImage == np.array([0,0,0]))black_wi = np.where(warpedImage == np.array([0,0,0]))print time.time() - tprint black_l[-1]for i in range(0, i1x):for j in range(0, i1y):try:if(np.array_equal(leftImage[j,i],np.array([0,0,0])) and  np.array_equal(warpedImage[j,i],np.array([0,0,0]))):# print "BLACK"# instead of just putting it with black, # take average of all nearby values and avg it.warpedImage[j,i] = [0, 0, 0]else:if(np.array_equal(warpedImage[j,i],[0,0,0])):# print "PIXEL"warpedImage[j,i] = leftImage[j,i]else:if not np.array_equal(leftImage[j,i], [0,0,0]):bw, gw, rw = warpedImage[j,i]bl,gl,rl = leftImage[j,i]# b = (bl+bw)/2# g = (gl+gw)/2# r = (rl+rw)/2warpedImage[j, i] = [bl,gl,rl]except:pass# cv2.imshow("waRPED mix", warpedImage)# cv2.waitKey()return warpedImagedef trim_left(self):passdef showImage(self, string=None):if string == 'left':cv2.imshow("left image", self.leftImage)# cv2.imshow("left image", cv2.resize(self.leftImage, (400,400)))elif string == "right":cv2.imshow("right Image", self.rightImage)cv2.waitKey()if __name__ == '__main__':try:args = sys.argv[1]except:args = "txtlists/files1.txt"finally:print "Parameters : ", argss = Stitch(args)s.leftshift()# s.showImage('left')s.rightshift()print "done"cv2.imwrite("test12.jpg", s.leftImage)print "image written"cv2.destroyAllWindows()

总结

图像拼接通常用到以下五个步骤:

图像拼接并非简单的将两张有共同区域的图像把相同的区域重合起来,由于两张图像拍摄的角度与位置不同,虽然有共同的区域,但拍摄时相机的内参与外参均不相同,所以简单的覆盖拼接是不合理的。因此,对于图像拼接需要以一张图像为基准对另外一张图像进行相应的变换(透视变换),然后将透视变换后的图像进行简单的平移后与基准图像的共同区域进行重合。

python+opencv实现多张图像拼接_附源码相关推荐

  1. 100个必会的python脚本-100行Python代码实现自动抢火车票(附源码)

    前言 又要过年了,今年你不妨自己写一段代码来抢回家的火车票,是不是很Cool.下面话不多说了,来一起看看详细的介绍吧. 先准备好: 12306网站用户名和密码 chrome浏览器及下载chromedr ...

  2. python opencv人脸识别考勤系统的完整源码

    这篇文章主要介绍了python opencv人脸识别考勤系统的完整源码,本文给大家介绍的非常详细,希望对大家的学习或工作具有一定的参考借鉴价值. 代码如下: import wx import wx.g ...

  3. 20220517 Python 制作一个儿童学习软件 (附源码和软件下载) 包含语音合成 视频播放 pyqt pptsx3 Qmovie request pygame 音频播放

    20220517 Python 制作一个儿童学习软件 (附源码和软件下载) 包含语音合成 视频播放 pyqt pptsx3 Qmovie request pygame 音频播放 文章目录 202205 ...

  4. Python毕设-【人脸签到系统】附源码/Python练手项目/Python毕业设计

    本人承诺只做技术分享,永不收费. V----------------->:专栏详情 文章目录 本人承诺只做技术分享,永不收费. V----------------->:专栏详情 一.背景 ...

  5. 用Python自动刷新抢12306火车票(附源码)

    專 欄 ❈ 作者:marvin,互联网从业者,现居上海张江 ❈ 一年一度的春运又来了,今年我自己写了个抢票脚本.使用Python+Splinter自动刷新抢票,可以成功抢到.(依赖自己的网络环境太厉害 ...

  6. 【Python】基于人脸识别的智能考勤系统(Pyqt5+MySQL+Opencv) [PC端部分-已附源码]

    [Python]基于人脸识别的考勤系统 [PC端部分] 一.项目简介 本项目编程语言Python3.6,编程工具pycharm,其他工具QT Designer.Navicat,表单信息保存在本地MyS ...

  7. 仅使用OpenCV实现活体检测!(附源码)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 我们先来看一个网络留言 △ 来自虾米妈咪 小朋友用妈妈的一寸照片通 ...

  8. python 使用pyserial控制温箱(附源码)

    目录 前言: 温箱介绍: 开始编码工作: 官方文档解读: (1)发送的数据格式介绍: (2)发送数据举例: 构建转换进制的类: 构建读取温箱温度的方法: (1)按照文档规则拼接命令: (2)将温箱返回 ...

  9. pyTorch入门(六)——实战Android Minist OpenCV手写数字识别(附源码地址)

    学更好的别人, 做更好的自己. --<微卡智享> 本文长度为4239字,预计阅读12分钟 前言 前面几篇文章实现了pyTorch训练模型,然后在Windows平台用C++ OpenCV D ...

最新文章

  1. 【强推】Blender制作逼真人物角色完整案例视频教程
  2. 实验5:配置通过静态工厂方法创建的bean、实例工厂方法创建的bean、(FactoryBean测试)★
  3. 配置MYSQL基于GTID 主从复制详细解析及步骤
  4. crt linux切换用户,不同连接终端通过密钥方式登录 Linux
  5. 10.30T2 二分+前缀和(后缀和)
  6. QDoc包括代码内联includecodeinline
  7. Nginx四层负载均衡模块添加
  8. java基本类型的默认值及其取值范围
  9. 玩Azkaban跳过的坑
  10. unix 获取程序占用内存_如何减少Docker和Kubernetes中的JVM应用程序内存占用
  11. 【Java】数据库编程
  12. windows浏览器访问虚拟机开的rabbitmq服务,无法访问
  13. cv如何连接mysql_Naicvat操作数据库的基本操作
  14. Linux下重启tomcat
  15. stm32f103测脉冲数用于带霍尔编码器的电机测速
  16. 一套键鼠同时控制三台电脑?罗技无线键鼠为办公效率加速
  17. html absolute溢出,position:absolute溢出处理
  18. 《嵌入式系统 – NUC980 IoT应用开发实战指南(基于RT-Thread系统)》第3章 NUC980 IoT I2C实践
  19. 软考中级真题 2015年上半年 系统集成项目管理工程师 应用技术
  20. html5写手机端页面

热门文章

  1. 详解各类型功放电路及原理
  2. 2022学科门类汇总
  3. ABP学习实践(十二)--模块系统
  4. 【HDLBits 刷题 4】Verilog Language(4)Procedures 和 More Verilog Features 部分
  5. JAVA高级学习笔记
  6. 八款堪称「神器」,却鲜为人知的办公利器
  7. 计算机科技最新发展,计算机最新技术发展趋势
  8. 如何在Google Chrome中为扩展程序创建自定义键盘快捷键
  9. 机械设计制造及其自动化要学计算机吗,机械设计制造及其自动化_专业解读_阳光高考...
  10. 谷歌浏览器iframe兼容问题_兼容解决 IE 、火狐、谷歌浏览器中 Iframe框架的页面缓存的方法...