OpenCV+OpenCvSharp实现图片特征向量提取与相似度计算

news2024/9/28 9:28:34

图片特征向量是一种用于描述图片内容的数学表示,它可以反映图片的颜色、纹理、形状等信息。图片特征向量可以用于做很多事情,比如图片检索、分类、识别等。

本文将介绍图片特征向量的提取以及相似度的计算,并使用C#来实现它们。

文章开始前,我们先来简单了解一下 OpenCV 和 OpenCvSharp4,这两个库是本文的核心。

什么是OpenCV

OpenCV(Open Source Computer Vision Library)是一个基于开源发行的跨平台计算机视觉和机器学习软件库,它支持多种编程语言,包含了数百种图像处理和计算机视觉算法。

什么是OpenCvSharp4

OpenCvSharp4 是一个基于 OpenCV 开发的跨平台图像处理库,它支持 .NET Framework 4.8+和 .NET Core 2.0+。它提供了丰富而易用的 API,可以实现各种图像处理功能。OpenCvSharp4 只包含核心的托管库,所以还需要另外安装对应操作系统的原生绑定包(OpenCvSharp4.runtime.*)。

图片特征向量提取

提取图片特征向量的方法有很多,本文将采用 SIFT 和 SURF 两种常用的算法。

SIFT算法

SIFT(Scale Invariant Feature Transform)算法是一种尺度不变的特征提取方法,它能够在不同的尺度空间中检测出稳定的关键点,并生成具有唯一性和不变性的描述符。SIFT 算法的主要优点是:

  • 尺度不变性:SIFT 算法使用了高斯金字塔来构建不同尺度的图像,并在每个尺度上进行极值点检测,从而实现了对尺度变化的不敏感。
  • 旋转不变性:SIFT 算法使用了梯度方向直方图来生成描述符,并根据关键点的主方向进行旋转归一化,从而实现了对旋转变化的不敏感。
  • 鉴别性强:SIFT 算法能够生成具有高维度和高信息量的描述符,使得每个关键点都具有唯一性和区分性,提高了匹配的可靠性。

使用 OpenCvSharp4 实现 SIFT 算法很简单,只需要调用SIFT.Create方法创建一个SIFT对象,然后调用DetectAndCompute方法从图片中提取特征点和描述符。下面是代码示例:

// 加载图片
Mat image1 = Cv2.ImRead("image1.jpg", ImreadModes.Grayscale);
Mat image2 = Cv2.ImRead("image2.jpg", ImreadModes.Grayscale);
​
// 创建SIFT对象
SIFT sift = SIFT.Create();
​
// 提取特征点和描述符
Mat descriptors1 = new Mat();
Mat descriptors2 = new Mat();
sift.DetectAndCompute(image1, null, out _, descriptors1);
sift.DetectAndCompute(image2, null, out _, descriptors2);
SURF算法

SURF(Speeded Up Robust Features)算法是一种快速而稳健的特征提取方法,它基于Harris角点检测和尺度不变特征变换(SIFT)算法改进而来。SURF 算法的主要优点是:

  • 速度快:SURF 算法使用了积分图和哈尔小波来加速特征点检测和描述符生成,比SIFT算法快几倍。
  • 稳健性高:SURF 算法对于旋转、缩放、亮度变化等干扰具有较好的鲁棒性,能够在不同的场景中保持稳定的性能。
  • 精度高:SURF 算法能够提取出高质量的特征点和描述符,提高了匹配的准确率。

使用 OpenCvSharp4 实现 SURF 算法也非常简单,只需要调用SURF.Create方法创建一个SURF对象,然后调用DetectAndCompute方法从图片中提取特征点和描述符。下面是代码示例:

// 加载图片
Mat image1 = Cv2.ImRead("image1.jpg", ImreadModes.Grayscale);
Mat image2 = Cv2.ImRead("image2.jpg", ImreadModes.Grayscale);
​
// 创建SURF对象
SURF surf = SURF.Create(500); // 500是阈值参数,表示特征点的最小响应值
​
// 提取特征点和描述符
Mat descriptors1 = new Mat();
Mat descriptors2 = new Mat();
surf.DetectAndCompute(image1, null, out _, descriptors1);
surf.DetectAndCompute(image2, null, out _, descriptors2);

图片相似度计算

提取了图片的特征向量后,我们就可以计算图片的相似度了。图片相似度的计算方法有很多,本文将介绍两种常用的方法:BFMatcher 和 FlannBasedMatcher,它们都是基于特征点匹配的方法,但是有一些区别。

BFMatcher

BFMatcher 是一种暴力匹配方法,它的原理是对于第一张图片中的每个特征点,都遍历第二张图片中的所有特征点,找出最接近的一个或多个特征点作为匹配结果。BFMatcher 的优点是简单直观,缺点是效率低,时间复杂度为 O(n^2),其中n是特征点的数量。

使用 OpenCvSharp4 实现 BFMatcher 也非常简单,只需要调用BFMatcher类的构造函数创建一个BFMatcher对象,然后调用Match方法进行匹配。下面是代码示例:

// 创建BFMatcher对象
BFMatcher bfMatcher = new BFMatcher(NormTypes.L2, false); // NormTypes.L2表示使用欧式距离作为相似度度量,false表示不交叉匹配
​
// 进行匹配
DMatch[] bfMatches = bfMatcher.Match(descriptors1, descriptors2); // bfMatches是一个数组,每个元素是一个DMatch对象,表示一对匹配结果
FlannBasedMatcher

FlannBasedMatcher 是一种近似最近邻匹配方法,它的原理是使用一种快速的索引结构来加速特征点的查找,从而降低时间复杂度。FlannBasedMatcher 的优点是效率高,缺点是精度略低,可能会出现一些错误的匹配。

使用 OpenCvSharp4 实现 FlannBasedMatcher 也非常简单,只需要调用FlannBasedMatcher类的构造函数创建一个FlannBasedMatcher对象,然后调用Match方法进行匹配。下面是代码示例:

// 创建FlannBasedMatcher对象
FlannBasedMatcher flannMatcher = new FlannBasedMatcher();
​
// 进行匹配
DMatch[] flannMatches = flannMatcher.Match(descriptors1, descriptors2); // flannMatches是一个数组,每个元素是一个DMatch对象,表示一对匹配结果
相似度得分

相似度得分的计算方法有很多,这里使用一种简单的方法:首先计算出每个匹配对的距离。然后对所有的距离求平均值,得到一个相似度得分,得分越小表示越相似。

我们对 BFMatcher 和 FlannBasedMatcher 的匹配结果都做了这个计算。

// 计算并显示BFMatcher和FlannBasedMatcher的相似度得分,得分越低越相似
Console.WriteLine("The score using BFMatcher is {0}", bfMatches.Average(m => m.Distance));
Console.WriteLine("The score using FlannBasedMatcher is {0}", flannMatches.Average(m => m.Distance));

这样,图片特征向量提取和相似度计算就实现了。完整代码可在公众号查看。

结果对比

接下来我们运行程序,从四种情况去查看结果。

1、两张完全不同的图片对比

这种情况下,我们可以预期得到很高的相似度得分,表示两张图片几乎没有相似之处。如图所示:

卡通人物

中度可信度描述已自动生成

SURF算法
The score using BFMatcher is 0.77414566
The score using FlannBasedMatcher is 0.77414566
SIFT算法
The score using BFMatcher is 366.84616
The score using FlannBasedMatcher is 372.25107
2、两张完全相同的图片对比

这种情况下,我们可以预期得到很低的相似度得分,表示两张图片完全一致。如图所示:

SURF算法
The score using BFMatcher is 0
The score using FlannBasedMatcher is 0
SIFT算法
The score using BFMatcher is 0
The score using FlannBasedMatcher is 0
3、某一张图片和它的部分截图进行对比

这种情况下,我们可以预期得到中等的相似度得分,表示两张图片有部分重合。如图所示:

SURF算法
The score using BFMatcher is 0.22462595
The score using FlannBasedMatcher is 0.23025486
SIFT算法
The score using BFMatcher is 105.93032
The score using FlannBasedMatcher is 108.3307
4、两张相似的图片进行对比

这种情况下,我们可以预期得到较低的相似度得分,表示两张图片有很多共同的特征。例如,我们可以使用两张不同角度拍摄的同一物体的图片进行对比。如图所示:

SURF算法
The score using BFMatcher is 0.37855583
The score using FlannBasedMatcher is 0.38878053
SIFT算法
The score using BFMatcher is 239.1525
The score using FlannBasedMatcher is 248.43388

从上面的结果可以看出,SURF 和 SIFT 算法都可以提取图片特征向量,同时,BFMatcher 和 FlannBasedMatcher 也有区别。因此,在选算法时,需要根据具体的应用场景和需求进行权衡。

如果你对此感兴趣,还可以进一步探究,将图片特征向量存储到向量数据库中,实现更多的功能需求。比如,你可以使用 Redis 或  Elasticsearch,它们都支持对向量数据进行增、删、改、查等操作。

以下是相关推荐阅读:

1、ChatGPT Embeddings与Redis强强结合实现文本相似度分析与搜索

2、利用Redis实现向量相似度搜索:解决文本、图像和音频之间的相似度匹配问题

3、C#+Redis Search:如何用Redis实现高性能全文搜索

写作不易,转载请注明博文地址,否则禁转!!!

👇感谢阅读,点赞+分享+收藏+关注👇
文章出自猿惑豁微信公众号

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文阅读——BART

Arxiv: https://arxiv.org/abs/1910.13461 一个去噪自编码器的预训练序列到序列的模型。是一个结合了双向和自回归transformers的模型。 预训练分为两个阶段:任意噪声函数破坏文本和序列模型重建原始文本 一、模型 input:被破坏的文本-->bidirecti…

折磨的Ts

先看下官网 这里的withDefault是给props设置默认值的 由于props传入了个函数在设置默认值的时候不知道怎么设置了 解决办法:直接不设置了。也不写了。

JAVA毕业设计106—基于Java+Springboot的外卖系统(源码+数据库)

基于JavaSpringboot的外卖系统(源码数据库)106 一、系统介绍 本系统分为用户端和管理端角色 前台用户功能: 登录、菜品浏览,口味选择,加入购物车,地址管理,提交订单。 管理后台: 登录,员工管…

四、【常用的几种抠图方式三】

文章目录 钢笔工具抠图通道抠图蒙版抠图色彩范围抠图 钢笔工具抠图 钢笔工具抠图适合边缘比较硬的主体对象,因此适合需要精修而且边缘比较生硬的图片,钢笔工具操作比较多,对一般的新手来讲不是很友好,想要使用好钢笔工具需要经常…

appium操控微信小程序的坑

appium操控微信小程序的坑 打不开启动页面driver的context只有NATIVE_APP小程序上元素找不到 我打算使用appium操控微信小程序,只要能够获取到小程序的页面元素就算成功。下面都是我遇到的问题。 打不开启动页面 以下是我的appium的配置参数和代码: de…

每日一练 | 华为认证真题练习Day123

1、下面哪项参数不能用于高级访问控制列表? A. 物理接口 B. 时间范围 C. 目的端口号 D. 协议号 2、ACL不会过滤设备自身产生的访问其它设备的流量;只过滤转发的流量,转发的流量中包括其它设备访问该设备的流量。 A. 对 B. 错 3、某个AC…

python读取Excel到mysql

常见问题: 1.数据库密码有特殊字符 使用urllib.parse.quote_plus 编译密码 mysql_engine create_engine((f"mysqlpymysql://root:%s10.0.0.2:3306/mydb")%urllib.parse.quote_plus("passaaaa")) 2.设置字段类型 设置特定类型,和指…

<多线程章节五>synchrosized的可重入特性

💐专栏导读 本篇文章收录于多线程,也欢迎翻阅博主的其他文章,可能也会让你有不一样的收获😄 🍁JavaSE 🌺多线程 🍂数据结构 💐synchrosized的可重入特性及死锁 可重入特性就是&…

汉威科技光纤预警系统,守护油气长输管道“大动脉”

石油、天然气早已成为城市生活中不可或缺的能源。广大车主能快速地加上汽油,千家万户能方便地用上天然气,得益于我国庞大的石油、天然气输送基础设施网络。 我国油气分布西多东少、北多南少,要想把千里、乃至万里之外的石油、天然气输送到中部…

降本增效的集成平台

降本增效的集成平台是企业数字化转型中的关键工具之一。它能够帮助企业解决传统集成方式面临的痛点,并满足企业在数字化转型过程中的需求。下面将重点讲解企业集成的痛点及需求、传统与全域集成的对比。 企业集成的痛点及需求: 系统孤岛和信息孤岛&…

uniapp vue2、vue3 页面模板代码块设置

本文分享 uniapp vue2、vue3 页面模板代码块设置 设置路径 HBuilder X -> 工具 -> 代码块设置 -> vue代码块 -> 自定义代码块 如上图操作后在打开的 vue.json 文件的右侧“自定义代码块”中复制如下代码(可全选替换也可添加到代码中) 示…

为何开发需要更多地考虑运维便利性

在当前的软件行业中,开发和运维是两个不可或缺的环节。然而,有时候我们会发现,一些软件开发人员过于关注开发的便捷性,而忽视了运维部署的复杂性。这种做法可能会导致开发出的软件部署难度大,甚至容易出现问题。因此&a…

【赠书活动】国家数据局正式揭牌,数据专业融合型人才迎来发展良机

摘要:新华社北京10月26日电 《中国证券报》26日刊发文章《国家数据局揭牌 数据要素产业进入加速发展期》。文章称,10月25日,国家数据局正式揭牌。业内人士认为,这标志着我国数字经济发展新阶段的开始,预计数据要素配套…

【数据结构】数组和字符串(七):特殊矩阵的压缩存储:三元组表的转置、加法、乘法操作

文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储b~c. 三角、对称矩阵的压缩存储d. 稀疏矩阵的压缩存储——三元组表4.2.3三元组表的转置、加法、乘法、操作转置加法乘法算法测试实验结果代码整合 4.2.1 矩阵的数组表示 【数据结构】数组和字符串…

Linux | 进程地址空间

目录 前言 一、初始进程地址空间 1、实验引入 2、虚拟地址空间 二、什么是进程地址空间 1、基本概念 2、深入理解进程地址空间 3、进程地址空间的本质 4、遗留问题解决 三、为什么要有进程地址空间 1、知识扩展 2、进程地址空间存在意义 3、重新理解挂起 前言 本…

[SQL开发笔记]SQL 别名:为表名称或列名称指定别名

一、功能描述: 通过使用 SQL,可以为表名称或列名称指定别名。基本上,创建别名是为了让列名称的可读性更强。 二、SQL 别名语法详解: (1)列的 SQL 别名语法: Select column_name AS alias_nam…

X86(32位)汇编指令与机器码转换原理

X86(32位)汇编指令与机器码转换原理 1 32位寻址形式下的ModR/M字节2 汇编指令转机器码2.1 mov ecx,[eaxebx*2]2.1.1 查Opcode和ModR/M2.1.2 查SIB 2.2 mov ecx,[eaxebx*210h]2.3 mov ecx,[eaxebx*200000100h] 本文属于《 X86指令基础系列教程》之一&…

Spring Cloud Gateway + Knife4j 4.3 接口文档整合和网关聚合

目录 前言Spring Cloud 整合 Knife4jpom.xmlapplication.ymlSwaggerConfig.java访问单服务接口文档 Spring Cloud Gateway 网关聚合pom.xmlapplication.yml访问网关聚合接口文档 接口测试**登录认证**获取登录用户信息 结语源码 前言 youlai-mall 开源微服务商城新版本基于 Sp…

数据库SqlServer笔试题

数据库SqlServer笔试题 一、数据库基础知识(通用)篇 1.说说主键、外键、超键、候选键 超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属 性组合在一起也可以作为一个超键。超键包含…

CSGO游戏搬砖的10个冷知识,90%的人还不知道

敲黑板了,同学们,很多人号一多就蒙圈,接下来解释一下buff号、Steam号、选品软件、识别码,桌面令牌,手机令牌,几者的关系: 1、前期一套实名只能绑定两个buff号,steam账号无需实名,后期…