图像拼接技术就是将数张有重叠部分的图像(可能是不同时间、不同视角或者不同传感器获得的)拼成一幅无缝的全景图或高分辨率图像的技术。
下面用opencv实现一下多张图像进行拼接
如下图所示,三张不同角度的图像最终拼接成一张全视角的图像


from imutils import paths
import numpy as np
import argparse
import imutils
import cv2# 构造参数解析器并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--images",default='images', type=str, required=True,help="path to input directory of images to stitch")
ap.add_argument("-o", "--output", default='output.png',type=str, required=True,help="path to the output image")
ap.add_argument("-c", "--crop", type=int, default=0,help="whether to crop out largest rectangular region")
args = vars(ap.parse_args())  # vars函数是实现返回对象object的属性和属性值的字典对象print(args)  # {'images': 'images/scottsdale', 'output': 'output.png', 'crop': 1}
# 匹配输入图像的路径并初始化我们的图像列表
# rectangular_region = 2
print("[INFO] loading images...")
# 获取到每张待拼接图像并排序,如['第一张图片路径', 第二张图片路径',第三张图片路径']
imagePaths = sorted(list(paths.list_images(args["images"])))
# print(imagePaths)
# imagePaths = ['IMG_1786-2.jpg',
#             'IMG_1787-2.jpg',
#             'IMG_1788-2.jpg']
images = []# 遍历图像路径,加载每个路径,然后将它们添加到我们的路径中图像到stich列表
for imagePath in imagePaths:image = cv2.imread(imagePath)images.append(image)# 初始化OpenCV的图像sticher对象,然后执行图像拼接
print("[INFO] stitching images...")
stitcher = cv2.createStitcher() if imutils.is_cv3() else cv2.Stitcher_create()
(status, stitched) = stitcher.stitch(images)# print(status, stitched)
# 如果状态为“0”,则OpenCV成功执行图像拼接
if status == 0:# 检查我们是否应该从拼接图像中裁剪出最大的矩形区域if args["crop"] > 0:# 在拼接图像周围创建一个10像素的黑色边框print("[INFO] cropping...")stitched = cv2.copyMakeBorder(stitched, 10, 10, 10, 10,cv2.BORDER_CONSTANT, (0, 0, 0))# cv2.imshow('123',stitched)# 将拼接图像转换为灰度gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY)# cv2.imshow('456', gray)# 对灰度图像进行阈值二值化,# 这样所有大于零的像素都设置为255(前景),而其他所有像素都保持为0(背景)thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]# cv2.imshow('789', thresh)# 在阈值图像中找到所有外部轮廓,然后找到 “最大 ”轮廓,它将是拼接图像的轮廓# cv2.RETR_EXTERNAL:只找外轮廓。cv2.CHAIN_APPROX_SIMPLE:输出少量轮廓点# 输出参数1:图像# 输出参数2:轮廓列表# 输出参数3:层级cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# print(cnts) #cnts包括三个数组:# print(len(cnts))cnts = imutils.grab_contours(cnts)################################# imutils.grab_contours 的源码 :# # if the length the contours tuple returned by cv2.findContours# # is '2' then we are using either OpenCV v2.4, v4-beta, or# # v4-official# if len(cnts) == 2:#     cnts = cnts[0]# # if the length of the contours tuple is '3' then we are using# # either OpenCV v3, v4-pre, or v4-alpha# elif len(cnts) == 3:#     cnts = cnts[1]# # otherwise OpenCV has changed their cv2.findContours return# # signature yet again and I have no idea WTH is going on# else:#     raise Exception(("Contours tuple must have length 2 or 3, "#                      "otherwise OpenCV changed their cv2.findContours return "#                      "signature yet again. Refer to OpenCV's documentation "#                      "in that case"))# # return the actual contours array# return cnts################################### 抓取具有最大区域的轮廓(即拼接图像本身的轮廓),cv2.contourArea是求轮廓面积c = max(cnts, key=cv2.contourArea)# print(c)# print(c.shape)# 为掩码分配内存,该掩码将包含拼接图像区域的矩形边界框mask = np.zeros(thresh.shape, dtype="uint8")# 计算出最大轮廓的边界框,使用边界矩形信息.使用 cv2.boundingRect(img) 函数,用一个最小的矩形,# 把找到的形状包起来,img是一个二值图,也就是它的参数;返回四个值,分别是 x,y,w,h;# 其中 x,y 是矩阵左上点的坐标,w,h 是矩阵的宽和高(x, y, w, h) = cv2.boundingRect(c)# 使用cv2.rectangle给图像加框,我们在mask上绘制一个纯白色矩形。# 参数1:图像# 参数2:左上角坐标# 参数3:右下角坐标# 参数4:框的颜色# 参数5:框的粗细cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1)# 创建掩码的两个副本# 第一个mask,将逐渐缩小,直到它可以放入全景内部。minRect = mask.copy()# 第二个mask,将用于确定是否需要继续减小minRect的大小。sub = mask.copy()cv2.imshow('111',sub)# 保持循环,直到sub中没有更多的前景像素# 对二值化图像执行countNonZero。可得到非零像素点数(即外边框的像素点)print(cv2.countNonZero(sub))while cv2.countNonZero(sub) > 0:# 执行侵蚀形态学操作以减小minRect的大小。minRect = cv2.erode(minRect, None)cv2.imshow('333',minRect)# 从minRect中减去thresh ,一旦minRect中没有更多的前景像素,我们就可以从循环中断开sub = cv2.subtract(minRect, thresh)# 在最小矩形掩码中找到轮廓,然后提取边界框(x,y) - 坐标cnts = cv2.findContours(minRect.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cv2.imshow('444',cnts[0])cnts = imutils.grab_contours(cnts)c = max(cnts, key=cv2.contourArea)(x, y, w, h) = cv2.boundingRect(c)# 使用边界框坐标来提取我们的最终拼接图像stitched = stitched[y:y + h, x:x + w]# 将输出拼接图像写入磁盘cv2.imwrite("result.jpg", stitched)# 将输出拼接图像显示到我们的屏幕cv2.imshow("Stitched", stitched)cv2.waitKey(0)# 否则,拼接失败,可能是由于检测不到足够的关键点else:print("[INFO] image stitching failed ({})".format(status))
#执行
python main.py --images images/ --output output.png --crop 1

结果如下所示

有一说一opencv真的牛掰

Opencv 实战五 图像拼接相关推荐

  1. [OpenCV实战]6 图像拼接和图像融合

    索引目录 1.问题描述 2.解决思路 3.程序算法 4.总结 参考 1.问题描述 将含有公共视野相同特征的两张图像拼接融合 2.解决思路 先使用sift算法对两张图像进行特征点提取和匹配,此时特征点过 ...

  2. OpenCV C++案例实战五《答题卡识别》

    OpenCV C++案例实战五<答题卡识别> 前言 一.图像矫正 1.源码 二.获取选项区域 1.扣出每题选项 2.源码 三.获取答案 1.思路 2.辅助函数 3.源码 4.效果 总结 前 ...

  3. Opencv实战 | 用摄像头自动化跟踪特定颜色物体

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:新机器视觉 1. 导语 在之前的某个教程里,我们探讨了如 ...

  4. 重磅升级,52个Python+OpenCV实战项目教你掌握图像处理

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 近期小白学视觉公众号推出了多篇Python+OpenCV实战项目的 ...

  5. OpenCV实战(1)——OpenCV与图像处理基础

    OpenCV实战(1)--OpenCV与图像处理基础 0. 前言 1. OpenCV 基础 1.1 安装 OpenCV 1.2 OpenCV 主要模块 1.3 使用 Qt 进行 OpenCV 开发 2 ...

  6. 再次升级,985博士整理的71个OpenCV实战项目教程开放下载!

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 近期小白学视觉公众号推出了多篇Python+OpenCV实战项目的 ...

  7. 基于OpenCV实战:3步实现图像降噪

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 在本文中,我们将展示如何通过三个简单的步骤来实现降噪.我们将使用机 ...

  8. 基于OpenCV实战:绘制图像轮廓(附代码)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 山区和地形图中海拔高的区域划出的线称为地形轮廓,它们提供了地形的高 ...

  9. 基于OpenCV实战:车牌检测

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 拥有思维导图或流程将引导我们朝着探索和寻找实现目标的正确道路的方向 ...

最新文章

  1. APP之红点提醒三个阶段
  2. 皮一皮:这是要红啊...
  3. html制作固定列的表格,带固定列的简单HTML表格
  4. 网站建设PHP中mysql和mysqli的区别
  5. mysql加删查语句_MySQL基本语句——增、删、查、改
  6. iphone6 充电电流测试软件,iPhone7支持快充? 9个充电器数据实测
  7. SpringBoot配置文件与配置类的属性映射方式
  8. `ECS弹性计算服务
  9. linux系统学习(常用命令)
  10. 定义m是第一个数,之后的每个数都是前一个的平方根,一共有n个数,计算总和。
  11. 1.2、SRv6(Segment Routing Over IPv6) 介绍
  12. python打造最强表白程序,Python 打造七夕最强表白程序
  13. VS2019安装和使用教程
  14. 问卷数据分析(SPSSSPSS Modeler)
  15. “茴”字有几种写法? Java 实现 WebSocket 的方式
  16. 使用adb命令管理应用
  17. 三位一体自荐信计算机专业,三位一体自荐信写法和范文
  18. 生成全排列算法的实现(Johnson-Trotter)
  19. python数据挖掘需要学的内容
  20. win7 svn客户端 不显示绿色小队号等问题

热门文章

  1. kafka opentracing
  2. 数据图表制作的4个基本要素!
  3. 麦田的守望者背景与分析
  4. ESP8266+电能计量芯片
  5. matlab指派问题求法,MATLAB实例:Munkres指派算法
  6. 设计师网页导航 php,设计师必须收藏的7个网址导航
  7. 《MacTalk 跨越边界》一一1.1 40岁了,还有没有路走?
  8. unity UGUI 九宫格 拉伸
  9. 使用百度大脑构建一个闲聊机器人
  10. Spark SQL PERCENTILE分析调研