《深度学习》OpenCV 图像拼接 原理、参数剖析、案例实现

[复制链接]
发表于 2026-1-15 02:34:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目次
一、图像拼接
1、直接看案例
图1与图2展示:
归并完效果:
2、什么是图像拼接
3、图像拼接步调
1)加载图像
2)特性点检测与形貌
3)特性点匹配
4)图像配准
5)图像变更和拼接
6)图像调解
二、案例实现
1、界说函数返回图像的关键点和形貌符
2、界说展示图像函数
3、盘算读入图像的特性点和形貌符
调试模式状态下:
kps对应值:
des对应值:
4、创建暴力匹配器和K近邻算法
1)关于BFMatcher暴力匹配
2)暴力匹配的K近邻
用法:
参数剖析:
返回值:
3)续接上文代码
运行效果:
调试模式rawMatches内容:
5、绘制匹配效果
运行效果:
6、盘算视角变更矩阵
调试模式下
kps_floatA与kps_floatB状态
matches状态
7、透视变更后拼接
运行效果:
8、完备代码:


一、图像拼接

1、直接看案例

        图1与图2展示:


        归并完效果:



2、什么是图像拼接

        图像拼接是指将多个图像拼接成一个大图像。在盘算机视觉和图像处置惩罚范畴,图像拼接常用于创建全景图像、创建大幅面照片、图像拼接等应用。

3、图像拼接步调


        1)加载图像

                利用OpenCV的cv::imread函数加载须要拼接的多个图像。
        2)特性点检测与形貌

                利用特性提取算法(如SIFT、ORB等)检测图像中的特性点,并盘算每个特性点的形貌符。
        3)特性点匹配

                利用特性匹配算法(如KNN匹配)来找到两个图像间的对应关系。常见的方法有基于隔断的匹配(如欧氏隔断、汉明隔断等)和基于相似性度量的匹配(如比率测试)。
        4)图像配准

                根据特性点的匹配效果,利用配准算法(如RANSAC)估计两个图像间的变更矩阵。常见的变更矩阵包罗仿射变更、透视变更等。
        5)图像变更和拼接

                利用估计得到的变更矩阵,将须要拼接的图像举行变更,并将它们拼接在一起。可以利用OpenCV的cv::warpPerspective函数或cv::warpAffine函数来实现变更和拼接。
        6)图像调解

                对拼接后的图像举行调解,使得拼接边沿平滑过渡,消除拼接处的不一连性。常见的方法包罗图像融合、图像平滑等。

二、案例实现

1、界说函数返回图像的关键点和形貌符

  1. import cv2
  2. import numpy as np
  3. import sys
  4. def detectAndDescribe(image):   # 函数用于
  5.     gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)   # 将影色园片转换成死没图
  6.     descriptor = cv2.SIFT_create()   # 建立SIFT生成器
  7.     (kps,des) = descriptor.detectAndCompute(gray,None)   # 读入参数为灰度图和可选参数掩膜,检测关键点及描述符,返回关键点列表和关键点对应的描述符列表,每个描述符都是一个向量,描述关键点周围图像内容
  8.     # 此处kps是元组类型,des是ndarry矩阵类型
  9.     # 将关键点列表的结果转换战NumPy数组
  10.     kps_float = np.float32([kp.pt for kp in kps])
  11.     # kp.pt 包含两个值,分别是关键点在图像中的 x 和 y 坐标。这些坐标通常是浮点数,可以精确的捕述关键点在图像中的位置
  12.     return (kps,kps_float,des)   # 返回特征点集,及对应的描述特征
复制代码


2、界说展示图像函数

  1. def cv_show(name,img):   # 函数用于展示图片
  2.     cv2.imshow(name,img)
  3.     cv2.waitKey(0)
复制代码

3、盘算读入图像的特性点和形貌符

  1. """读取拼接图片"""
  2. imageA = cv2.imread("1.jpg")
  3. cv_show('imageA',imageA)
  4. imageB = cv2.imread("2.jpg")
  5. cv_show("imageB",imageB)
  6. """计算图片特征点及描述符"""
  7. (kpsA,kps_floatA,desA) = detectAndDescribe(imageA)
  8. (kpsB,kps_floatB,desB) = detectAndDescribe(imageB)
复制代码
        调试模式状态下:

                kps对应值:


                des对应值:



4、创建暴力匹配器和K近邻算法

        1)关于BFMatcher暴力匹配

                在图像处置惩罚中,特性点匹配是指在差别图像中找到对应的特性点。BFMatcher可用于在两个特性向量聚会合盘算最佳匹配。它通过盘算两个特性向量的相似度(如欧氏隔断、汉明隔断等),并选择迩来邻的特性点作为匹配点。
        
        2)暴力匹配的K近邻

                用法:

  1. 使用KNN检测来自A、B图的SIFT特征匹配对
  2. # knnMatch(gueryDescriptors, trainDescriptors, k, mask=None, compactResult=None)
复制代码
                参数剖析:

                        queryDescriptors:匹配图像A的形貌符
                        trainDescriptors:匹配图像B的形貌符
                        K:最佳匹配的形貌符个数,一样寻常K=2
                        mask 可选参数:一个掩码数组,用于过滤不须要匹配的特性点。默以为None,表现不利用掩码。
                        compactResult 可选参数:一个布尔值,指定是否返回紧凑的匹配效果。默以为None,表现根据特性形貌符的范例主动选择。
        
                返回值:

                        distance:匹配的特性点形貌符的欧式隔断,数值越小也就阐明俩个特性点越相近
                        queryIdx:测试图像的特性点形貌符的下标(第几个特性点形貌符),同时也是形貌符对应特性点的下标。
                        trainIdx:样本图像的特性点形貌符下标,同时也是形貌符对应特性点的下标。

        3)续接上文代码

  1. matcher = cv2.BFMatcher()
  2. rawMatches = matcher.knnMatch(desB,desA,2)   # 对desB中的每个描述符在desA中查找两个最近邻
  3. good = []   # 设置空列表用于存放匹配成功的特征点
  4. matches =[]   # 用于存放匹配成功的两个点的索引值
  5. for m in rawMatches:
  6.     # 当最近距离跟次近距离的比值小于0.65值时,保留此匹配对
  7.     if len(m) == 2 and m[0].distance < 0.65 * m[1].distance:  # len(m) == 2 表示检查是否有两个匹配项
  8.         # m[0].distance < 0.65 * m[1].distance表示判断匹配的两个点最近邻和次近邻的比值是否小于0.65
  9.         good.append(m)
  10.         # 存储两个点在featuresA,featuresB中的索引值
  11.         matches.append((m[0].trainIdx, m[0].queryIdx))
  12. print(len(good))  # 返回匹配成功的特征点个数
  13. print(matches)   # 打印匹配成功点的索引
复制代码
                运行效果:


                调试模式rawMatches内容:



5、绘制匹配效果

  1. # 绘制两组关键点的匹配结果,输入参数为B图原图,B图的关键点列表,A图原图,A图的关键点列表,匹配成功的点的坐标,掩码图像默认为None
  2. # flag 表示绘制的标志,cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS表示在关键点周围绘制圆圈,圆圈大小与关键点尺度成比例
  3. vis = cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  4. cv_show('keypoint matches',vis)
复制代码
        运行效果:



6、盘算视角变更矩阵

  1. """透视变换"""
  2. if len(matches) > 4 :  # 当前筛选后的匹配对大于4.计算视角变换矩阵
  3.     # 分别获取匹配成功的A图中点的坐标与B图中点的坐标
  4.     ptsA = np.float32([kps_floatA[i] for (i,_) in matches])   # kps_floatA是匹配成功点的坐标,matches是通过阈值筛选之后的特征点对象,其中存放匹配成功点的索引,
  5.     ptsB = np.float32([kps_floatB[i] for (_,i) in matches])   # kps_floatB是图片B中的全就特征点坐标
  6.     (H, mask) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC,  10)
  7. else:
  8.     print('图片未找到4个以上的匹配点')
  9.     sys.exit()
复制代码
        调试模式下

                kps_floatA与kps_floatB状态


                matches状态



7、透视变更后拼接

  1. # 根据视角变换矩阵H将原图B进行透视变换,然后将变换后的图片与A进行拼接
  2. result = cv2.warpPerspective(imageB,H,(imageB.shape[1] + imageA.shape[1],imageB.shape[0]))
  3. cv_show('resultB',result)
  4. # 将图片A传入result图片最左端
  5. result[0:imageA.shape[0],0:imageA.shape[1]] = imageA
  6. cv_show('result',result)
复制代码
        运行效果:




8、完备代码:

  1. import cv2
  2. import numpy as np
  3. import sys
  4. def cv_show(name,img):  
  5.     cv2.imshow(name,img)
  6.     cv2.waitKey(0)
  7. def detectAndDescribe(image):   
  8.     gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
  9.     descriptor = cv2.SIFT_create()  
  10.     (kps,des) = descriptor.detectAndCompute(gray,None)   
  11.     return (kps,kps_float,des)   
  12. imageA = cv2.imread("1.jpg")
  13. cv_show('imageA',imageA)
  14. imageB = cv2.imread("2.jpg")
  15. cv_show("imageB",imageB)
  16. (kpsA,kps_floatA,desA) = detectAndDescribe(imageA)
  17. (kpsB,kps_floatB,desB) = detectAndDescribe(imageB)
  18. rawMatches = matcher.knnMatch(desB,desA,2)   
  19. good = []   
  20. matches =[]   
  21. for m in rawMatches:
  22.    
  23.     if len(m) == 2 and m[0].distance < 0.65 * m[1].distance:  
  24.         good.append(m)
  25.         
  26.         matches.append((m[0].trainIdx, m[0].queryIdx))
  27. print(len(good))  # 返回匹配成功的特征点个数
  28. print(matches)   # 打印匹配成功点的索引
  29. vis = cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  30. cv_show('keypoint matches',vis)
  31. if len(matches) > 4 :  
  32.     ptsA = np.float32([kps_floatA[i] for (i,_) in matches])   
  33.     ptsB = np.float32([kps_floatB[i] for (_,i) in matches])   
  34.     (H, mask) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC,  10)
  35. else:
  36.     print('图片未找到4个以上的匹配点')
  37.     sys.exit()  # 退出匹配
  38. result = cv2.warpPerspective(imageB,H,(imageB.shape[1] + imageA.shape[1],imageB.shape[0]))
  39. cv_show('resultB',result)
  40. result[0:imageA.shape[0],0:imageA.shape[1]] = imageA
  41. cv_show('result',result)
复制代码

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表