机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)

摘要:
1.sift.detectAndComputer(gray,None)#计算出图像的关键点和sift特征向量参数说明:gray表示输入的图片2.cv2.findHomography(kpA,kpB,cv2.RANSAC,reproThresh)#计算出单应性矩阵参数说明:kpA表示图像A关键点的坐标,kpB图像B关键点的坐标,使用随机抽样一致性算法来进行迭代,reproThresh表示每次抽取样本

1. sift.detectAndComputer(gray, None) # 计算出图像的关键点和sift特征向量

参数说明:gray表示输入的图片

2.cv2.findHomography(kpA, kpB, cv2.RANSAC, reproThresh) # 计算出单应性矩阵

参数说明:kpA表示图像A关键点的坐标, kpB图像B关键点的坐标, 使用随机抽样一致性算法来进行迭代,reproThresh表示每次抽取样本的个数

3.cv2.warpPespective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageA.shape[0])) # 获得根据单应性矩阵变化后的图像

参数说明:image表示输入图像,H表示单应性的矩阵,(imageA.shape[1] + imageB.shape[1], imageA.shape[0])表示矩阵变化后的维度

4. cv2.line(imageA, kpsA, imageB, kpsB, (0,0,255), 2) 进行画出直线的操作
参数说明:imageA和imageB表示输入图片, kpsA和kpsB表示关键点的坐标(x, y) ,(0, 0, 255)表示颜色, 2表示直线的宽度

RANSAC算法(随机抽样一致性算法), 对于左边的图,可以看到使用最小二乘法尽可能多的满足点可以分布在拟合曲线周围,减小均分根误差,因此拟合的曲线在一定程度上容易发生偏离,而RANSAC却不会出现这种情况

机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)第1张

RANSCA原理, 因为拟合一条直线只需要两个点,因此我们每次随机选取两个点,做出直线,划定一个距离,判断落在直线周围距离范围点的个数,不断的迭代,直到找出拟合的直线,使得点落在上面最多的拟合曲线

机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)第2张

图像拼接的关键是在于对图像进行变化,变化后的点与需要拼接的图片中的sift点,越接近,即欧式距离越短,对图像拼接的过程中,至少需要有4对特征点,求取变化矩阵Hi

机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)第3张

我们使用RANSAC不断去取随机从两个图像中取4对的sift特征点,计算出H,定义损失值,即x’,与x的距离,即y‘与y的距离之和是否是最小值,不断迭代,找出最佳的H

上述就是计算出来了H值,也就是变化矩阵

代码思路:

第一步:对图像进行灰度化,使用sift.detectAndCompute(image, None) 进行ksp关键点,dpSIFT特征向量,将kps进行向量化操作,即kps.pt

第二步:构建BMFmatch匹配器,获得符合条件的匹配值,matches获得的是ksp关键点的匹配值得索引,使用索引获得符合条件的kspA和kspB

第三步:使用cv2.findHomography(kpA, kpB, cv2.RANSAC,reproThresh) 随机抽取4个点,求得最合适的H变化矩阵

第四步:使用获得的变化矩阵H, cv.warpPerspective 对imageA求取变化后的图像

第五步:将imageB加入到变化后的图像获得最终图像

第六步:如果需要进行展示,构造新的图像,尺寸为imageA.shape[0], imageB.shape[1] +imageA.shape[1], 使用matches的索引,使用cv2.line将符合条件的点进行连接

第七步:返回最终的结果,进行画图展示

importcv2
importnumpy as np
importmatplotlib.pyplot as plt


classStitcher:

    def stitch(self, imgs, ratio=0.75, reproThresh=4, showMathes =False):

        (imageB, imageA) =imgs
        #第一步:计算kpsA和dpsA
        (kpsA, dpsA) =self.detectandcompute(imageA)
        (kpsB, dpsB) =self.detectandcompute(imageB)
        #获得变化的矩阵H
        M =self.matchKeypoint(kpsA, dpsA, kpsB, dpsB, ratio, reproThresh)

        if M isNone:
            returnNone
        (matches, H, status) =M

        #第四步:使用cv2.warpPerspective获得经过H变化后的图像
        result = cv2.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageB.shape[0]))
        
        #第五步:将图像B填充到进过H变化后的图像,获得最终的图像
        result[0:imageB.shape[0], 0:imageB.shape[1]] =imageB

        ifshowMathes:
            #第六步:对图像的关键点进行连接
            via =self.showMatches(imageA, imageB, kpsA, kpsB, matches, status)

            return(via, result)

        returnresult



        #进行画图操作


    defshowMatches(self, imageA, imageB, kpsA, kpsB, matches, status):
        #将两个图像进行拼接
        #根据图像的大小,构造全零矩阵
        via = np.zeros((max(imageB.shape[0], imageA.shape[0]), imageA.shape[1] + imageB.shape[1], 3), np.uint8)
        #将图像A和图像B放到全部都是零的图像中
        via[0:imageA.shape[0], 0:imageA.shape[1]] =imageA
        via[0:imageB.shape[0], imageA.shape[1]:] =imageB
        #根据matches中的索引,构造出点的位置信息
        for (trainIdx, queryIdx), s inzip(matches, status):
            if s==1:
                ptA = (int(kpsA[queryIdx][0]), int(kpsA[queryIdx][1]))
                ptB = (int(kpsB[trainIdx][0] + imageA.shape[1]), int(kpsB[trainIdx][1]))
                #使用cv2.line进行画图操作
                cv2.line(via, ptA, ptB, (0, 255, 0), 1)

        returnvia




    defmatchKeypoint(self, kpsA, dpsA, kpsB, dpsB, ratio, reproThresh):

        #第二步:实例化BFM匹配, 找出符合添加的关键点的索引
        bf =cv2.BFMatcher()

        matcher = bf.knnMatch(dpsA, dpsB, 2)

        matches =[]

        for match inmatcher:

            if len(match) == 2 and match[0].distance < match[1].distance *ratio:
                #加入match[0]的索引
matches.append((match[0].trainIdx, match[0].queryIdx))
        #第三步:使用cv2.findHomography找出符合添加的H矩阵
        if len(matches) > 4:
            #根据索引找出符合条件的位置
            kpsA = np.float32([kpsA[i] for (_, i) inmatches])
            kpsB = np.float32([kpsB[i] for (i, _) inmatches])
            (H, status) =cv2.findHomography(kpsA, kpsB, cv2.RANSAC, reproThresh)

            return(matches, H, status)
        returnNone


    defcv_show(self, img, name):
        cv2.imshow(name, img)


    defdetectandcompute(self, image):
        #进行灰度值转化
        gray =cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        #实例化sift函数
        sift =cv2.xfeatures2d.SIFT_create()
        #获得kps关键点和dps特征向量sift
        kps, dps =sift.detectAndCompute(gray, None)
        #获得特征点的位置信息, 并转换数据类型
        kps = np.float32([kp.pt for kp inkps])

        return (kps, dps)

机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)第4张机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)第5张机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)第6张

使用cv2.warpPesctive即根据H变化后的图片 经过图像拼接后的result图片 经过图片关键点连接的图片

免责声明:文章转载自《机器学习进阶-案例实战-图像全景拼接-图像全景拼接(RANSCA) 1.sift.detectAndComputer(获得sift图像关键点) 2.cv2.findHomography(计算单应性矩阵H) 3.cv2.warpPerspective(获得单应性变化后的图像) 4.cv2.line(对关键点位置进行连线画图)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mycat 1.6.6.1安装以及配置docker 安装mysql 5.7.24 双主多从读写分离主主切换PostgreSQL之 使用扩展Extension下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

机器学习策略(二)---误差分析、训练集与开发测试集不相配怎么办、迁移学习/多任务学习、端到端深度学习

1.误差分析 1.1 误差分析 当算法还没有到达human level时,你需要去分析算法带来的误差,并且决定接下去应该如何优化,从而减小误差。这个过程叫做误差分析。 将设在猫狗分类的任务上,若dev set上的error有10%,此时你需要找出这些错误的case,然后统计猫错分成狗,和狗错分成猫各自的比例,如果你发现:狗错分成猫的比例是5%猫错分成狗的比...

三种Js深度学习框架介绍

谈到机器学习,我们脑海首先蹦出的编程语言是什么?一定是python。其实除了python,JavaScript也是不错的选择。都说现在是大前端时代,从移动开发、服务器端,甚至桌面软件开发(比如大名鼎鼎的VS Code),都有JavaScript的身影。   用Javascript写机器学习应用,当然不会从头开始手写机器学习算法和模型,通常会借助现有框架。我...

CNN网络的基本介绍(二)

四、激活函数 激活函数又称非线性映射,顾名思义,激活函数的引入是为了增加整个网络的表达能力(即非线性)。若干线性操作层的堆叠仍然只能起到线性映射的作用,无法形成复杂的函数。常用的函数有sigmoid、双曲正切、线性修正单元函数等等。 使用一个神经网络时,需要决定使用哪种激活函数用隐藏层上,哪种用在输出节点上。    比如,在神经网路的前向传播中,这两步会使...

【学习笔记】卷积神经网络

目录 人工神经网络VS卷积神经网络 卷积神经网络CNN 卷积层 参数及结构 卷积输出值的计算 步长 外围补充与多Filter 总结输出大小 卷积网络API 新的激活函数-Relurule激活函数API Pooling计算Pooling API Mnist数据集卷积网络实现 人工神经网络VS卷积神经网络 参数太多,在cifar-...

最大熵模型和EM算法

一、极大似然已经发生的事件是独立重复事件,符合同一分布已经发生的时间是可能性(似然)的事件利用这两个假设,已经发生时间的联合密度值就最大,所以就可以求出总体分布f中参数θ 用极大似然进行机器学习有监督学习:最大熵模型无监督学习:GMM 二、熵和信息自信息i(x) = -log(p(x)) 信息是对不确定性的度量。概率是对确定性的度量,概率越大,越确定,可能...

评估机器学习模型的几种方法(验证集的重要性)

什么是评估机器学习模型       机器学习的目的是得到可以泛化(generalize)的模型,即在前所未见的数据上表现很好的模型,而过拟合则是核心难点。你只能控制可以观察的事情,所以能够可靠地衡量模型的泛化能力非常重要。   如何衡量泛化能力,即如何评估机器学习模型。 评估模型的重点是将数据划分为三个集合:训练集、验证集和测试集。在训练数据上训练模型,在...