位置: IT常识 - 正文

Opencv实战——图像拼接(opencv官方教程)

编辑:rootadmin
Opencv实战——图像拼接 文章目录前言实现方法实现代码直接拼接加权处理总结前言

推荐整理分享Opencv实战——图像拼接(opencv官方教程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:opencv详解,opencv图像处理入门,opencv实战项目教程,opencv图像处理入门,opencv教程,opencv tutorials,opencv tutorial,opencv tutorial,内容如对您有帮助,希望把文章链接给更多的朋友!

  图像拼接(Image Stitching)是一种利用实景图像组成全景空间的技术,它将多幅图像拼接成一幅大尺度图像或360度全景图,接可以看做是场景重建的一种特殊情况,其中图像仅通过平面单应性进行关联。图像拼接在运动检测和跟踪,增强现实,分辨率增强,视频压缩和图像稳定等机器视觉领域有很大的应用。   图像拼接的输出是两个输入图像的并集。通常用到四个步骤: 特征提取(Feature Extraction):检测输入图像中的特征点。

图像配准(Image Registration):建立了图像之间的几何对应关系,使它们可以在一个共同的参照系中进行变换、比较和分析。

图像变形(Warping):图像变形是指将其中一幅图像的图像重投影,并将图像放置在更大的画布上。

图像融合(Blending):图像融合是通过改变边界附近的图像灰度级,去除这些缝隙,创建混合图像,从而在图像之间实现平滑过渡。混合模式(Blend modes)用于将两层融合到一起。

实现方法

1、用SIFT提取图像中的特征点,并对每个关键点周围的区域计算特征向量。可以使用比SIFT快的SURF方法,但是我的opencv版本为最新版,不知道是专利的原因还是什么原因用SURF = cv2.xfeatures2D.SURF_create ()实例化的时候会报错,网上说可以退opencv版本,但是我这里没有尝试,就用了sift = cv2.SIFT_create()。 2、在分别提取好了两张图片的关键点和特征向量以后,可以利用它们进行两张图片的匹配。在拼接图片中,可以使用Knn进行匹配,但是使用FLANN快速匹配库更快,图片拼接,需要用到FLANN的单应性匹配。 3、单应性匹配完之后可以获得透视变换H矩阵,用这个的逆矩阵来对第二幅图片进行透视变换,将其转到和第一张图一样的视角,为下一步拼接做准备。 4、透视变化完后就可以直接拼接图片了,将图片通过numpy直接加到透视变化完成的图像的左边,覆盖掉重合的部分,得到拼接图片,但是这样拼接得图片中间会有一条很明显的缝隙,可以通过加权平均法,界线的两侧各取一定的比例来融合缝隙,速度快,但不自然。或者羽化法,或者拉普拉斯金字塔融合,效果最好。在这里用的是加权平均法,可以把第一张图叠在左边,但是对第一张图和它的重叠区做一些加权处理,重叠部分,离左边图近的,左边图的权重就高一些,离右边近的,右边旋转图的权重就高一些,然后两者相加,使得过渡是平滑地,这样看上去效果好一些,速度就比较慢。

实现代码Opencv实战——图像拼接(opencv官方教程)

先给出原图

直接拼接#导入库import cv2import numpy as npimport sysfrom PIL import Image#图像显示函数def show(name,img): cv2.imshow(name, img) cv2.waitKey(0) cv2.destroyAllWindows()#读取输入图片ima = cv2.imread("you.jpg")imb = cv2.imread("zuo.jpg")A = ima.copy()B = imb.copy()imageA = cv2.resize(A,(0,0),fx=0.2,fy=0.2)imageB = cv2.resize(B,(0,0),fx=0.2,fy=0.2)#检测A、B图片的SIFT关键特征点,并计算特征描述子def detectAndDescribe(image): # 建立SIFT生成器 sift = cv2.SIFT_create() # 检测SIFT特征点,并计算描述子 (kps, features) = sift.detectAndCompute(image, None) # 将结果转换成NumPy数组 kps = np.float32([kp.pt for kp in kps]) # 返回特征点集,及对应的描述特征 return (kps, features)#检测A、B图片的SIFT关键特征点,并计算特征描述子kpsA, featuresA = detectAndDescribe(imageA)kpsB, featuresB = detectAndDescribe(imageB)# 建立暴力匹配器bf = cv2.BFMatcher()# 使用KNN检测来自A、B图的SIFT特征匹配对,K=2matches = bf.knnMatch(featuresA, featuresB, 2)good = []for m in matches: # 当最近距离跟次近距离的比值小于ratio值时,保留此匹配对 if len(m) == 2 and m[0].distance < m[1].distance * 0.75: # 存储两个点在featuresA, featuresB中的索引值 good.append((m[0].trainIdx, m[0].queryIdx))# 当筛选后的匹配对大于4时,计算视角变换矩阵if len(good) > 4: # 获取匹配对的点坐标 ptsA = np.float32([kpsA[i] for (_, i) in good]) ptsB = np.float32([kpsB[i] for (i, _) in good]) # 计算视角变换矩阵 H, status = cv2.findHomography(ptsA, ptsB, cv2.RANSAC,4.0)# 匹配两张图片的所有特征点,返回匹配结果M = (matches, H, status)# 如果返回结果为空,没有匹配成功的特征点,退出程序if M is None: print("无匹配结果") sys.exit()# 否则,提取匹配结果# H是3x3视角变换矩阵(matches, H, status) = M# 将图片A进行视角变换,result是变换后图片result = cv2.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageA.shape[0]))# 将图片B传入result图片最左端result[0:imageB.shape[0], 0:imageB.shape[1]] = imageBshow('res',result)print(result.shape)

效果:   可以发现直接拼接虽然可以拼接但是在拼接的地方会有一条很明显的缝隙,不过直接拼接的速度比较快只用了2点多秒。

加权处理

  我们通常使用alpha因子,通常称为alpha通道,它在中心像素处的值为1,在与边界像素线性递减后变为0。当输出拼接图像中至少有两幅重叠图像时,我们将使用如下的alpha值来计算其中一个像素处的颜色:假设两个图像,在输出图像中重叠;每个像素点在图像,其中(R,G,B)是像素的颜色值,我们将在缝合后的输出图像中计算(x, y)的像素值: 代码如下:

import cv2import numpy as npfrom matplotlib import pyplot as pltimport timedef show(name,img): cv2.imshow(name, img) cv2.waitKey(0) cv2.destroyAllWindows()MIN = 10FLANN_INDEX_KDTREE = 0starttime = time.time()img1 = cv2.imread('zuo.jpg') #queryimg2 = cv2.imread('you.jpg') #trainimageA = cv2.resize(img1,(0,0),fx=0.2,fy=0.2)imageB = cv2.resize(img2,(0,0),fx=0.2,fy=0.2)surf=cv2.xfeatures2d.SIFT_create()#可以改为SIFT#sift = cv2.SIFT_create()kp1,descrip1 = sift.detectAndCompute(imageA,None)kp2,descrip2 = sift.detectAndCompute(imageB,None)#创建字典indexParams = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)searchParams = dict(checks=50)flann=cv2.FlannBasedMatcher(indexParams,searchParams)match=flann.knnMatch(descrip1,descrip2,k=2)good=[]#过滤特征点for i,(m,n) in enumerate(match): if(m.distance<0.75*n.distance): good.append(m)# 当筛选后的匹配对大于10时,计算视角变换矩阵if len(good) > MIN: src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2) ano_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2) M,mask = cv2.findHomography(src_pts,ano_pts,cv2.RANSAC,5.0) warpImg = cv2.warpPerspective(imageB, np.linalg.inv(M), (imageA.shape[1]+imageB.shape[1], imageB.shape[0])) direct=warpImg.copy() direct[0:imageA.shape[0], 0:imageB.shape[1]] =imageA simple=time.time()show('res',warpImg)rows,cols=imageA.shape[:2]print(rows)print(cols)for col in range(0,cols): # 开始重叠的最左端 if imageA[:, col].any() and warpImg[:, col].any(): left = col print(left) breakfor col in range(cols-1, 0, -1): #重叠的最右一列 if imageA[:, col].any() and warpImg[:, col].any(): right = col print(right) break#加权处理res = np.zeros([rows, cols, 3], np.uint8)for row in range(0, rows): for col in range(0, cols): if not imageA[row, col].any(): # 如果没有原图,用旋转的填充 res[row, col] = warpImg[row, col] elif not warpImg[row, col].any(): res[row, col] = imageA[row, col] else: srcImgLen = float(abs(col - left)) testImgLen = float(abs(col - right)) alpha = srcImgLen / (srcImgLen + testImgLen) res[row, col] = np.clip(imageA[row, col] * (1 - alpha) + warpImg[row, col] * alpha, 0, 255)warpImg[0:imageA.shape[0], 0:imageA.shape[1]]=resshow('res',warpImg)final=time.time()print(final-starttime)

效果:   可以发现经过加权处理融合后的图片要比直接拼接效果要好,但是时间用了差不多16秒,而且还是有一条黑缝,目前还没有找到解决的办法,有好方法的友友们可以在评论区留意哟。

总结

  除了加权处理的方法外,还可以尝试用羽化和拉普拉斯金字塔等方法来实现图像拼接,这里给出实现的原理,方便以后尝试。 羽化(原文连接):  加载原始图像并找到轮廓。

 模糊原始图像并将其保存在不同的变量中。

 创建一个空的蒙版并在其上绘制检测到的轮廓。

 使用 np.where() 方法从要模糊值的蒙版(轮廓)中选择像素,然后替换它。

拉普拉斯金字塔(原文连接);

本文链接地址:https://www.jiuchutong.com/zhishi/300365.html 转载请保留说明!

上一篇:这几个SQL语法的坑,你踩过吗(这几个sql语法的区别)

下一篇:《花雕学AI》06:抢先体验ChatGPT的九个国内镜像站之试用与综合评测(花雕典故)

  • 怎样玩游戏赚钱月入上万?(怎样玩游戏赚钱请你告诉我)

    怎样玩游戏赚钱月入上万?(怎样玩游戏赚钱请你告诉我)

  • 抖音把粉丝移除了通知吗(抖音把粉丝移除了对方还能加回来吗)

    抖音把粉丝移除了通知吗(抖音把粉丝移除了对方还能加回来吗)

  • 会员下载歌曲怎么永久(会员下载歌曲怎么变成永久的)

    会员下载歌曲怎么永久(会员下载歌曲怎么变成永久的)

  • 荣耀20可以插耳机吗(荣耀20插耳机没反应)

    荣耀20可以插耳机吗(荣耀20插耳机没反应)

  • 为什么电脑屏幕出现两层(为什么电脑屏幕不显示,但是开机了)

    为什么电脑屏幕出现两层(为什么电脑屏幕不显示,但是开机了)

  • 快手怎么把评论隐藏了(快手怎么把评论设置自己可见)

    快手怎么把评论隐藏了(快手怎么把评论设置自己可见)

  • iphone的天气无法显示(iphone天气无法使用)

    iphone的天气无法显示(iphone天气无法使用)

  • airpods每次打开电量不一样(airpods每次打开都要重新配对)

    airpods每次打开电量不一样(airpods每次打开都要重新配对)

  • 10lite什么型号(华为10lite参数)

    10lite什么型号(华为10lite参数)

  • 苹果11pro是磨砂的吗(苹果11pro磨砂黑后盖用久了会掉漆吗)

    苹果11pro是磨砂的吗(苹果11pro磨砂黑后盖用久了会掉漆吗)

  • 电话电池不耐用怎么办(电话手机电池不耐用了怎么办)

    电话电池不耐用怎么办(电话手机电池不耐用了怎么办)

  • 闲鱼等待见面交易是什么意思(闲鱼等待见面交易怎么改为邮寄)

    闲鱼等待见面交易是什么意思(闲鱼等待见面交易怎么改为邮寄)

  • 手机主板坏了能开机吗(手机主板坏了能打电话吗)

    手机主板坏了能开机吗(手机主板坏了能打电话吗)

  • 苹果6s无服务怎么修复(iphone6s手机无服务)

    苹果6s无服务怎么修复(iphone6s手机无服务)

  • 苹果xr死机的原因(iphonexr手机死机)

    苹果xr死机的原因(iphonexr手机死机)

  • 影拓和wacom的区别(wacom- intuos pro(影拓pro))

    影拓和wacom的区别(wacom- intuos pro(影拓pro))

  • 4g电信卡突然上不了网(电信卡4g突然变2g怎么回事)

    4g电信卡突然上不了网(电信卡4g突然变2g怎么回事)

  • 华为手机系统软件怎么卸载(华为手机系统软件更新)

    华为手机系统软件怎么卸载(华为手机系统软件更新)

  • 手机整点报时怎么取消(手机整点报时怎么关闭)

    手机整点报时怎么取消(手机整点报时怎么关闭)

  • 戴尔电脑打不开怎么办(戴尔电脑打不开设置界面)

    戴尔电脑打不开怎么办(戴尔电脑打不开设置界面)

  • vivo手机分辨率在哪调(vivo s16分辨率)

    vivo手机分辨率在哪调(vivo s16分辨率)

  • 荣耀v20拍照有防抖功能吗(荣耀x20拍照有防抖功能吗)

    荣耀v20拍照有防抖功能吗(荣耀x20拍照有防抖功能吗)

  • 苹果12系统如何截图(苹果12系统如何升级)

    苹果12系统如何截图(苹果12系统如何升级)

  • 小米手机关机键在哪儿(小米手机关机键坏了怎么重启)

    小米手机关机键在哪儿(小米手机关机键坏了怎么重启)

  • 怎样改ppt上的文字(怎样改ppt上的文字内容)

    怎样改ppt上的文字(怎样改ppt上的文字内容)

  • 锁屏快资讯怎么删除(锁屏资讯怎么打开)

    锁屏快资讯怎么删除(锁屏资讯怎么打开)

  • 快手发作品怎么定位别的地方(快手发作品怎么关闭位置)

    快手发作品怎么定位别的地方(快手发作品怎么关闭位置)

  • 花呗分期专享额度在哪(花呗分期专享额度怎么刷出来)

    花呗分期专享额度在哪(花呗分期专享额度怎么刷出来)

  • 已申报税额是什么意思,要交吗
  • 增值税销项税额公式
  • 新企业所得税季初资产总额
  • 发票丢失的税务处罚
  • 领发票凭证做什么用
  • 客户维护费计入什么科目
  • 农产品普通发票抵扣政策
  • 进项认证勾选在哪里操作
  • 货代企业都需要交什么税
  • 合同款未付怎么写欠条
  • 前期差错更正会引起所有者权益总额变动吗
  • 专项产资金支出要怎么做分录?
  • iphone手机腾讯视频怎么取消自动续费
  • 普通发票要纳税吗
  • 个人无偿受赠房屋 个人所得税 张英泉
  • 建筑工程确认收入条件
  • 预缴所得税多交了汇算时可以抵扣下一年的所得税吗
  • 增加采购发票的方法
  • 以前年度未申报的专项附加扣除
  • 笔记本windows10截屏
  • 股权变更需要缴纳印花税吗,缴纳多少
  • 政府搬迁补偿款不够建房怎么办
  • Vue3+element-plus 后台管理系统(含登陆注册功能页面)
  • 资产负债表要点
  • controller 层
  • php rtrim
  • php验证源码
  • 库存商品转在建工程 增值税
  • php生成guid
  • php语言之面向对象编程 educoder
  • 会计账目和账户的区别
  • 在php中提供了什么函数用于删除数组中的元素
  • 长期股权投资的核算方法
  • 【创作赢红包】项目信息分析表
  • javascript基础类型
  • 金蝶销售明细查不出来
  • 可供出售金融资产的会计处理
  • 已付款收货未收到发票怎么做账
  • 普通发票网络服务系统
  • 去年的电费能查到吗
  • mysql中You can’t specify target table for update in FROM clause错误解决方法
  • 娱乐服务计费销售额包括
  • 外经证预缴税款网上申报
  • 销售货物物流运输丢失取得赔偿款需要缴纳企业所得税吗
  • 盈余公积的用途主要是
  • 公司的固定资产怎么处理
  • 发票保管应由谁保管
  • 认缴出资额承担责任怎么算
  • 水果店的账务处理
  • 缴纳工会筹备金应该记什么科目
  • 私营公司无形资产怎么算
  • 记账凭证的基本要素包括哪些
  • mysql高级功能
  • distinct 多个
  • xp如何给文件夹加密码
  • 启用与禁用的英文
  • solaris版本查询
  • pe下修改windows下的盘符
  • win10怎么自定义壁纸
  • Win10预览版镜像
  • centos安装nmtui
  • WIN7系统如何禁止特定软件在线升级
  • dw导入excel
  • 两个js文件互相取变量
  • node js入门
  • js修改地址栏参数但不让他跳转
  • 用python画一棵树
  • python remote
  • javascript运用
  • js鼠标拖动窗口的做法
  • js水平垂直居中怎么设置
  • 使用jQuery Rotare实现微信大转盘抽奖功能
  • 甘肃国家税务发票查询
  • 国家税务总局财政部公告2023年第11号
  • 深圳市国家税务局电子税务局官网
  • 山东水利建设基金减免政策
  • 财税招商专员是做什么的
  • 国税局可以办理什么业务
  • 企业报税年报如何填写
  • 四川社保缴费后多久生效
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设