学习笔记:Opencv实现图像特征提取算法SIFT

2023.8.19

为了在暑假内实现深度学习的进阶学习,特意学习一下传统算法,分享学习心得,记录学习日常

SIFT的百科:

SIFT = Scale Invariant Feature Transform, 尺度不变特征转换

全网最详细SIFT算法原理实现_ssift算法_Tc.小浩的博客-CSDN博客

在环境配置中要配置opencv:

pip install opencv-contrib-python

SIFT算法的三个计算步骤:

  1,在DOG尺度空间中获取特征点;

  2,关键点的方向估计(寻找主方向)

  3,通过各关键点的特征向量(关键点的描述子生成)

进行两两比较找出相互匹配的若干对特征点,建立两图间景物间的对应关系,可以基于SIFT实现图像拼接

Code of SIFT and lena:

 注意你是否有lena.png图像

import cv2 as cv

img = cv.imread('lena.png')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
# sift = cv.SIFT_create()
kp = sift.detect(gray, None)
img = cv.drawKeypoints(gray, kp, img)
cv.imshow("SIFT", img)
cv.imwrite('sift_keypoints.jpg', img)
cv.waitKey(0)
cv.destroyAllWindows()

Result is shown in these figrues : SIFT 提取了lena的特征点 

 基于SIFT的图片实现图片拼接:

   代码是Copy大神的,注意有两个代码,运行第二个喔。代码所用的图片也附上!

import numpy as np
import cv2


class Stitcher:

    # 拼接函数
    def stitch(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):
        # 获取输入图片
        (imageB, imageA) = images
        # 检测A、B图片的SIFT关键特征点,并计算特征描述子
        (kpsA, featuresA) = self.detectAndDescribe(imageA)
        (kpsB, featuresB) = self.detectAndDescribe(imageB)

        # 匹配两张图片的所有特征点,返回匹配结果
        M = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)

        # 如果返回结果为空,没有匹配成功的特征点,退出算法
        if M is None:
            return None

        # 否则,提取匹配结果
        # 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]] = imageB

        # 检测是否需要显示图片匹配
        if showMatches:
            # 生成匹配图片
            vis = self.drawMatches(imageA, imageB, kpsA, kpsB, matches, status)
            # 返回结果
            return (result, vis)

        # 返回匹配结果
        return result

    def detectAndDescribe(self, image):
        # 将彩色图片转换成灰度图
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        # 建立SIFT生成器
        descriptor = cv2.xfeatures2d.SIFT_create()

        # 检测SIFT特征点,并计算描述子
        (kps, features) = descriptor.detectAndCompute(image, None)

        # 将结果转换成NumPy数组
        kps = np.float32([kp.pt for kp in kps])
        print(kps)

        # 返回特征点集,及对应的描述特征
        return (kps, features)

    def matchKeypoints(self, kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh):
        # 建立暴力匹配器
        matcher = cv2.DescriptorMatcher_create("BruteForce")

        # 使用KNN检测来自A、B图的SIFT特征匹配对,K=2
        rawMatches = matcher.knnMatch(featuresA, featuresB, 2)

        matches = []
        for m in rawMatches:
            # 当最近距离跟次近距离的比值小于ratio值时,保留此匹配对
            if len(m) == 2 and m[0].distance < m[1].distance * ratio:
                # 存储两个点在featuresA, featuresB中的索引值
                matches.append((m[0].trainIdx, m[0].queryIdx))

        # 当筛选后的匹配对大于4时,计算视角变换矩阵
        if len(matches) > 4:
            # 获取匹配对的点坐标
            ptsA = np.float32([kpsA[i] for (_, i) in matches])
            ptsB = np.float32([kpsB[i] for (i, _) in matches])

            # 计算视角变换矩阵
            (H, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, reprojThresh)

            # 返回结果
            return (matches, H, status)

        # 如果匹配对小于4时,返回None
        return None

    def drawMatches(self, imageA, imageB, kpsA, kpsB, matches, status):
        # 初始化可视化图片,将A、B图左右连接到一起
        (hA, wA) = imageA.shape[:2]
        (hB, wB) = imageB.shape[:2]
        vis = np.zeros((max(hA, hB), wA + wB, 3), dtype="uint8")
        vis[0:hA, 0:wA] = imageA
        vis[0:hB, wA:] = imageB

        # 联合遍历,画出匹配对
        for ((trainIdx, queryIdx), s) in zip(matches, status):
            # 当点对匹配成功时,画到可视化图上
            if s == 1:
                # 画出匹配对
                ptA = (int(kpsA[queryIdx][0]), int(kpsA[queryIdx][1]))
                ptB = (int(kpsB[trainIdx][0]) + wA, int(kpsB[trainIdx][1]))
                cv2.line(vis, ptA, ptB, (0, 255, 0), 1)

        # 返回可视化结果
        return vis
from Stitcher import Stitcher
import cv2

# 读取拼接图片
imageA = cv2.imread("image/left_01.png")
imageB = cv2.imread("image/right_01.png")

# 把图片拼接成全景图
stitcher = Stitcher()
(result, vis) = stitcher.stitch([imageA, imageB], showMatches=True)

# 显示所有图片
cv2.imshow("Image A", imageA)
cv2.imshow("Image B", imageB)
cv2.imshow("Keypoint Matches", vis)
cv2.imshow("Result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

                                                            代码使用的图片

 效果是这样:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/80978.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

hive高频使用的拼接函数及“避坑”

hive高频使用的拼接函数及“避坑” 说到拼接函数应用场景和使用频次还是非常高&#xff0c;比如一个员工在公司充当多个角色&#xff0c;我们在底层存数的时候往往是多行&#xff0c;但是应用的时候我们通常会只需要一行&#xff0c;角色字段进行拼接&#xff0c;这样join其他…

Mariadb高可用MHA

目录 前言 一、概述 &#xff08;一&#xff09;、概念 &#xff08;二&#xff09;、组成 &#xff08;三&#xff09;、特点 &#xff08;四&#xff09;、工作原理 二、案例 &#xff08;一&#xff09;、构建MHA 1.所有节点ssh免密登录 2、MySQL主从复制 &#x…

【计算机设计大赛】国赛一等奖项目分享——基于多端融合的化工安全生产监管可视化系统

文章目录 一、计算机设计大赛国赛一等奖二、项目背景三、项目简介四、系统架构五、系统功能结构六、项目特色&#xff08;1&#xff09;多端融合&#xff08;2&#xff09;数据可视化&#xff08;3&#xff09;计算机视觉&#xff08;目标检测&#xff09; 七、系统界面设计&am…

【ESP系列】ESP01S官方MQTT案例实验

前言 偶然发现安信可官网有ESP01S和STM32连接TCP和MQTT的案例。弄了一两天&#xff0c;把我使用的流程在这里记录下。MQTT的固件一定要烧录进去&#xff0c;默认固件是没有MQTT相关的AT指令的。 环境 Keli5&#xff0c;STM32F103C8T6 官方Keil工程链接&#xff1a;ESP8266的S…

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效…

换过3个工作,我却得出10年测试人的血泪经验

我跟大多数IT职场的测试新人起点差不多&#xff0c;在测试的这条路上&#xff0c;没有天生的聪明天资&#xff0c;也没有一个耀眼的学历。在北京这样一个随便一个同事不是清华的本硕&#xff0c;就是北邮北航的硕士下&#xff0c;自己也常常感到惭愧。 自己从事测试多年&#…

【SLAM】ORBSLAM34macOS: ORBSLAM3 Project 4(for) macOS Platform

文章目录 配置ORBSLAM34macOS 版本运行步骤&#xff1a;版本修复问题记录&#xff1a;编译 fix运行 fix 配置 硬件&#xff1a;MacBook Pro Intel CPU 系统&#xff1a;macOS Ventura 13.4.1 ORBSLAM34macOS 版本 https://github.com/phdsky/ORB_SLAM3/tree/macOS 运行步骤&…

【模拟集成电路】反馈系统——基础到进阶(一)

【模拟集成电路】反馈系统——基础到进阶 前言1 概述2 反馈电路特性2.1增益灵敏度降低2.2 终端阻抗变化2.3 带宽拓展2.4 非线性减小 3 放大器分类4 反馈检测和返回机制4.1 按照检测物理量分类4.2 按照检测拓扑连接分类 5 反馈结构分析6 二端口方法7 波特方法6 麦德布鲁克方法 前…

归并排序:从二路到多路

前言 我们所熟知的快速排序和归并排序都是非常优秀的排序算法。 但是快速排序和归并排序的一个区别就是&#xff1a;快速排序是一种内部排序&#xff0c;而归并排序是一种外部排序。 简单理解归并排序&#xff1a;递归地拆分&#xff0c;回溯过程中&#xff0c;将排序结果进…

Android12之com.android.media.swcodec无法生成apex问题(一百六十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

源于传承,擎领未来,新架构、新工艺下的“换心工程”——金融电子化访中电金信副总经理、研究院院长况文川

当前&#xff0c;商业银行的经营环境正在发生着深刻而复杂的变化&#xff0c;在深化改革主旋律的指引下&#xff0c;数字化转型已成为我国商业银行普遍认同、广泛采用的战略性举措。核心系统作为承载银行业务的关键支柱系统&#xff0c;一直是各银行在金融科技建设中重点关注和…

多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)

多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)。 一个新项目,后端使用 PHP 实现,前端不做路由,提供一个模板,由后端路由控制。 Route::get(pages/{name}, [\App\Http\Controllers\ResourceController::class, getResourceVersion])

Redis数据结构——快速列表quicklist、快表

定义 Redis中的数据结构&#xff0c;链表和压缩列表这两种数据结构是列表对象的底层实现方式。 当时考虑到链表的附加空间太大&#xff0c;节点的内存都是单独分配的&#xff0c;还会导致内存碎片化问题严重。 因此从Redis3.2开始&#xff0c;对列表的底层数据结构进行了改造&…

css学习1

1、样式定义如何显示元素。 2、样式通常保存至外部的css文件中。 3、样式可以使内容与表现分离。 4、css主要有两部分组成&#xff1a;选择器与一条或多条声明。 选择器通常为要改变的html元素&#xff0c;每条声明由一个属性和一个值组成。每个属性有一个值&#xff0c;属性…

C语言编程:最小二乘法拟合直线

本文研究通过C语言实现最小二乘法拟合直线。 文章目录 1 引入2 公式推导3 C语言代码实现4 测试验证5 总结 1 引入 最小二乘法&#xff0c;简单来说就是根据一组观测得到的数值&#xff0c;寻找一个函数&#xff0c;使得函数与观测点的误差的平方和达到最小。在工程实践中&…

leetcode15. 三数之和

这里保证1.元素a不会重复。2.所有解都是有序的。3.b和c元素不重复。所以解不会重复。 class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {std::vector<std::vector<int>> result;if (nums.size() < 3) return …

提升大数据技能,不再颓废!这6家学习网站是你的利器!

随着国家数字化转型&#xff0c;大数据领域对人才的需求越来越多。大数据主要研究计算机科学和大数据处理技术等相关的知识和技能&#xff0c;从大数据应用的三个主要层面&#xff08;即数据管理、系统开发、海量数据分析与挖掘&#xff09;出发&#xff0c;对实际问题进行分析…

更多openEuler镜像加入AWS Marketplace!

自2023年7月openEuler 22.03 LTS SP1正式登陆AWS Marketplace后&#xff0c;openEuler社区一直持续于在AWS上提供更多版本。 目前&#xff0c;openEuler22.03 LTS SP1 ,SP2两个版本及 x86 arm64两种架构的四个镜像均可通过AWS对外提供&#xff0c;且在亚太及欧洲15个Region开放…

UML图绘制 -- 类图

1.类图的画法 类 整体是个矩形&#xff0c;第一层类名&#xff0c;第二层属性&#xff0c;第三层方法。 &#xff1a;public- : private# : protected空格: 默认的default 对应的类写法。 public class Student {public String name;public Integer age;protected I…

深入理解【二叉树】

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…