python3.7 + opencv3.4.5的图像融合

最近在看关于图像融合的内容:
主要的步骤就是:
1.特征检测
2.特征匹配
3.求取单应性矩阵
4.图像投影变换
5.图像合并

本文章采用的是python3.7 + opencv3.4.5
由于特征检测和匹配需要用到sift算法或者surf算法,而由于专利问题,在 opencv3中将该算法放在了opencv_contrib中 所以需要下载opencv_contrib(3.4.5)以及cmake进行重编译
(最新的opencv4.4中 由于专利到期 sift和surf已经回到了opencv中 哈哈 好消息呀 )
具体的配置请参考上一篇文章
https://blog.csdn.net/dg1011/article/details/114833424

本文是基于其他参考进行的改写
https://blog.csdn.net/lla520/article/details/77488332

关于几种匹配算法的比较:
https://blog.csdn.net/zilanpotou182/article/details/66478915

SURF与SIFT的比较
1 方法比较
(1)在生成尺度空间方面,SIFT算法利用的是差分高斯金字塔与不同层级的空间图像相互卷积生成。
SURF算法采用的是不同尺度的box filters与原图像卷积

(2)在特征点检验时,SIFT算子是先对图像进行非极大值抑制,再去除对比度较低的点。然后通过Hessian矩阵去除边缘的点。
而SURF算法是先通过Hessian矩阵来检测候选特征点,然后再对非极大值的点进行抑制

(3)在特征向量的方向确定上,SIFT算法是在正方形区域内统计梯度的幅值的直方图,找到最大梯度幅值所对应的方向。SIFT算子确定的特征点可以有一个或一个以上方向,其中包括一个主方向与多个辅方向。
SURF算法则是在圆形邻域内,检测各个扇形范围内水平、垂直方向上的Haar小波响应,找到模值最大的扇形指向,且该算法的方向只有一个。

(4)SIFT算法生成描述子时,是将的采样点划分为的区域,从而计算每个分区种子点的幅值并确定其方向,共计128维。
SURF算法在生成特征描述子时将的正方形分割成的小方格,每个子区域25个采样点,计算小波haar响应,一共64维。

综上,SURF算法在各个步骤上都简化了一些繁琐的工作,仅仅计算了特征点的一个主方向,生成的特征描述子也与前者相比降低了维数。

2.效果比较:
加速3倍
亮度变化下效果好
模糊方面优于SIFT
尺度不变性不及SIFT
旋转不变上差很多

以上比较部分源自:
https://blog.csdn.net/lucifer_24/article/details/88823448?spm=1001.2014.3001.5501

附上代码

import numpy as np
import cv2

#图像路径
imgname1 = 'rr.jpg' #右图
imgname2 = 'll.jpg' #左图

surf = cv2.xfeatures2d.SURF_create()

# FLANN 参数设计
#这里使用的是KTreeIndex配置索引,指定待处理核密度树的数量(理想的数量在1-16)
#值越高结果越准确,但是消耗的时间也越多。实际上,匹配效果很大程度上取决于输入。
# 5kd-trees和50checks总能取得合理精度,而且短时间完成。
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)

#图像读取
img1 = cv2.imread(imgname1)
img2 = cv2.imread(imgname2)
cv2.imshow("img1",img1)
cv2.imshow("img2",img2)
cv2.waitKey(0)

# gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #灰度处理图像
# gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# cv2.imshow("gray1", gray1)
# cv2.imshow("gray2", gray2)
# cv2.waitKey(0)

kp1, des1 = surf.detectAndCompute(img1,None)#des是描述子
kp2, des2 = surf.detectAndCompute(img2,None)
img3 = cv2.drawKeypoints(img1,kp1,np.array([]))#绘制特征点
img4 = cv2.drawKeypoints(img2,kp2,np.array([]))
cv2.imshow("kp1", img3)
cv2.imshow("kp2", img4)
cv2.waitKey(0)

matches = flann.knnMatch(des1,des2,k=2)#匹配特征点
goodMatches = []
for m,n in matches:#更佳匹配
    # ratio = 0.4:对于准确度要求高的匹配;
    # ratio = 0.6:对于匹配点数目要求比较多的匹配;
    # ratio = 0.5:一般情况下。
    if m.distance < 0.4 * n.distance:
        goodMatches.append(m)
img5 = cv2.drawMatches(img3,kp1,img4,kp2,goodMatches,None,flags=2)#绘制匹配结果
cv2.imshow("SURF", img5)
cv2.waitKey(0)

#注意trainIdx和queryIdx的对应关系
image2Points = np.float32([ kp2[m.trainIdx].pt for m in goodMatches ])
image1Points = np.float32([ kp1[m.queryIdx].pt for m in goodMatches ])
#求取单应性矩阵homo
homo, mask = cv2.findHomography(image1Points, image2Points, cv2.RANSAC, 5.0)
print(homo)

#计算右图投影变换后四个顶点
#右侧的两个顶点就是最终图像的最右侧的两个顶点
#四个匹配点对就可以确定唯一的一个投影变换矩阵
h = img1.shape[0]
w = img1.shape[1]
trainBorder = np.float32([[[0, 0], [w, 0], [w, h], [0, h]]])
queryBorder = cv2.perspectiveTransform(trainBorder, homo)
print(queryBorder)

#将右图投影变换成和左图同一坐标系中的对应点
size = (max(queryBorder[0][1][0], queryBorder[0][2][0]), max(img2.shape[0], queryBorder[0][2][1]))
imageTransform = cv2.warpPerspective(img1, homo, size)
cv2.imshow("imageTransform", imageTransform)
cv2.waitKey(0)

#将左图直接复制到转换后的图像上
#注意:python中问对应的copyto函数
dst = np.zeros(imageTransform.shape)
#不可以使用  dst = imageTransform  这样创建的是软连接
# 这样做在接下来的操作会使imageTransform的值改变
dst = imageTransform.copy()
dst[0:img2.shape[0], 0:img2.shape[1]] = img2
cv2.imshow("dst", dst)
cv2.waitKey(0)

#加权融合图像
start = min(queryBorder[0][0][0], queryBorder[0][3][0])
DoubleWidth = img2.shape[1] - start
alpha = 1
for i in range(dst.shape[0]):
    theLeft = dst[i]
    theRight = imageTransform[i]
    for j in range(int(start), img2.shape[1]):
        if sum(theRight[j]) == 0:
            alpha = 0
        else:
            alpha = (j - start) / DoubleWidth
        for k in range(3):
            dst[i][j][k] = theLeft[j][k] * (1 - alpha) + theRight[j][k] * alpha
cv2.imshow("result", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

由于ORB算法的检测结果为二进制
因此需要在

matches = flann.knnMatch(des1,des2,k=2)#匹配特征点

前加上数据类型转换

des1 = np.float32(des1)
des2 = np.float32(des2)

不过在本文的实例中 ORB算法检测出来的特征点个数偏少 无法使用 哈哈

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python 3.7 和 opencv-python 是两个不同的库,分别用于不同的用途。 Python 3.7 是一种编程语言,它是 Python 编程语言系列的最新版本。Python 是一种高级编程语言,具有简洁、易学、易读的特点,被广泛应用于科学计算、数据分析、人工智能、网络编程等领域。Python 3.7 是 Python 语言的一个新版本,增加了一些新的功能和语法,提高了性能和稳定性。 而 opencv-python 是一个基于 Python 的开源计算机视觉库,它提供了一系列用于图像处理和计算机视觉任务的函数和工具。opencv-python 扩展了 Python 的功能,使得开发者可以轻松地处理图像和视频数据,进行图像处理、特征提取、目标检测、图像识别等任务。它被广泛应用于计算机视觉、机器学习、人工智能等领域。 Python 3.7 和 opencv-python 可以配合使用,以完成图像处理和计算机视觉相关的任务。通过使用 Python 3.7 编写代码,并借助 opencv-python 提供的函数和工具,我们可以实现图像的读取、保存、处理、显示等操作,还可以进行目标检测、特征提取、图像识别等高级计算机视觉任务。 在使用 Python 3.7 和 opencv-python 时,我们需要确保安装了正确的版本。Python 3.7 可以通过官方网站下载并安装。而 opencv-python 可以通过 pip 命令安装,例如使用以下命令安装最新版本: pip install opencv-python 然后,我们可以在 Python 3.7 的环境中导入 opencv-python 函数库,并使用其中的函数和工具进行图像处理和计算机视觉任务的实现。 总之,Python 3.7 和 opencv-python 是分别用于编程和计算机视觉的两个库,它们可以配合使用,以实现图像处理和计算机视觉相关的任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值