C#结合OpenCVSharp4图片相似度识别
OpenCVSharp4图片相似度识别
需求背景:需要计算两个图片的相似度,然后将相似的图片进行归纳
1. 图片相似度算法
由于我是CRUD后端仔,对图像处理没什么概念。因此网上调研了几种相似度算法分析其适用场景。
直方图算法
获取要比较的2个图片的直方图数据,然后再将直方图数据归一化比较,最终得到一个相似指数,通过设定相似指数的边界,以此判断是否相同图片。
平均值哈希算法 aHash
转灰度压缩之后计算均值,最终通过像素比较得出哈希值,速度很快,但敏感度很高,稍有变化就会极大影响判定结果,精准度较差。因此比较适用于缩略图比较,最常用的就是以图搜图
感知哈希算法 pHash
在均值哈希基础上加入DCT
(离散余弦变化),两次DCT
就可以很好的将图像按照频度分开,取左上角高能低频信息做均值哈希,因此,精确度很高,但是速度方面较差一些。相比较aHash
,pHash
更加适合用于缩略图比较,也非常适合比较两个近似图片是否相等。
差异值哈希算法 dHash
灰度压缩之后,比较相邻像素之间差异。假设有10×10的图像,每行10个像素,就会产生9个差异值,一共10行,就一共有9×10=90个差异值。最终生成哈希值即指纹。速度上来说,介于aHash
和pHash
之间,精准度同样也介于aHash
和pHash
之间。
结构相似性算法 SSIM
SSIM(structural similarity)
,结构相似性,是一种衡量两幅图像相似度的指标。SSIM
算法主要用于检测两张相同尺寸的图像的相似度、或者检测图像的失真程度。原论文中,SSIM
算法主要通过分别比较两个图像的亮度,对比度,结构,然后对这三个要素加权并用乘积表示。
SSIM
算法在设计上考虑了人眼的视觉特性,它能够考虑到图像的结构信息在人的感知上的模糊变化,该模型还引入了一些与感知上的变化有关的感知现象,包含亮度mask和对比mask,结构信息指的是像素之间有着内部的依赖性,尤其是空间上靠近的像素点。这些依赖性携带着目标对象视觉感知上的重要信息。
经过调研对比,这里就选择SSIM
算法。
2. 下载OpenCVSharp4
通过NuGet包管理器进行下载。搜索OpenCVSharp4
下载。
请注意其描述信息:OpenCV wrapper for .NET. Since this package includes only core managed libraries, another package of native bindings for your OS is required (OpenCvSharp4.runtime.*).
这是说:OpenCV 包只是一个核心库,如需在你的系统上使用,还需要对应的运行时包,这里是Windows系统,因此还需下载 OpenCvSharp4.runtime.win
3. 使用
在项目中引入OpenCvSharp
using OpenCvSharp;
由于OpenCVSharp4
没有直接提供封装SSIM
算法的接口,因此需要自行写这部分代码。完整代码如下
public Scalar Compare_SSIM(string imgFile1, string imgFile2)
{
var image1 = Cv2.ImRead(imgFile1);
var image2Tmp = Cv2.ImRead(imgFile2);
// 将两个图片处理成同样大小,否则会有错误: The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array'
var image2 = new Mat();
Cv2.Resize(image2Tmp, image2, new OpenCvSharp.Size(image1.Size().Width, image1.Size().Height));
double C1 = 6.5025, C2 = 58.5225;
var validImage1 = new Mat();
var validImage2 = new Mat();
image1.ConvertTo(validImage1, MatType.CV_32F); //数据类型转换为 float,防止后续计算出现错误
image2.ConvertTo(validImage2, MatType.CV_32F);
Mat image1_1 = validImage1.Mul(validImage1); //图像乘积
Mat image2_2 = validImage2.Mul(validImage2);
Mat image1_2 = validImage1.Mul(validImage2);
Mat gausBlur1 = new Mat(), gausBlur2 = new Mat(), gausBlur12 = new Mat();
Cv2.GaussianBlur(validImage1, gausBlur1, new OpenCvSharp.Size(11, 11), 1.5); //高斯卷积核计算图像均值
Cv2.GaussianBlur(validImage2, gausBlur2, new OpenCvSharp.Size(11, 11), 1.5);
Cv2.GaussianBlur(image1_2, gausBlur12, new OpenCvSharp.Size(11, 11), 1.5);
Mat imageAvgProduct = gausBlur1.Mul(gausBlur2); //均值乘积
Mat u1Squre = gausBlur1.Mul(gausBlur1); //各自均值的平方
Mat u2Squre = gausBlur2.Mul(gausBlur2);
Mat imageConvariance = new Mat(), imageVariance1 = new Mat(), imageVariance2 = new Mat();
Mat squreAvg1 = new Mat(), squreAvg2 = new Mat();
Cv2.GaussianBlur(image1_1, squreAvg1, new OpenCvSharp.Size(11, 11), 1.5); //图像平方的均值
Cv2.GaussianBlur(image2_2, squreAvg2, new OpenCvSharp.Size(11, 11), 1.5);
imageConvariance = gausBlur12 - gausBlur1.Mul(gausBlur2);// 计算协方差
imageVariance1 = squreAvg1 - gausBlur1.Mul(gausBlur1); //计算方差
imageVariance2 = squreAvg2 - gausBlur2.Mul(gausBlur2);
var member = ((2 * gausBlur1.Mul(gausBlur2) + C1).Mul(2 * imageConvariance + C2));
var denominator = ((u1Squre + u2Squre + C1).Mul(imageVariance1 + imageVariance2 + C2));
Mat ssim = new Mat();
Cv2.Divide(member, denominator, ssim);
var sclar = Cv2.Mean(ssim);
return sclar; // 变化率,即差异
}
实际检测效果如下
这两幅图的相似度大约是92.21%,基本符合预期
这两幅图居然还有约18%的相似度,根据SSIM
算法特性,这应该是图片大小的相似。
虽然也是拿来主义,毕竟我不是研究算法的大佬,需要站在巨人肩膀上干活~
做个笔记。
C#结合OpenCVSharp4图片相似度识别的更多相关文章
- atitit.图片相似度与图片查找的设计 获取图片指纹
atitit.图片相似度与图片查找的设计. 1. 两张图片相似算法 1 2. DCT(离散余弦变换(DiscreteCosineTransform))编辑 2 3. 编辑距离编辑 3 4. Java ...
- opencv学习笔记(六)直方图比较图片相似度
opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...
- e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (二) 图片验证码的识别
上一篇文章讲了“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 一 京东 商品搜索 ...
- iOS,OC,图片相似度比较,图片指纹
上周,正在忙,突然有个同学找我帮忙,说有个需求:图片相似度比较. 网上搜了一下,感觉不是很难,就写了下,这里分享给需要的小伙伴. 首先,本次采用的是OpenCV,图片哈希值: 先说一下基本思路: 1. ...
- python 对比图片相似度
最近appium的使用越来越广泛了,对于测试本身而言,断言同样是很重要的,没有准确的断言那么就根本就不能称之为完整的测试了.那么目前先从最简单的截图对比来看.我这里分享下python的图片相似度的代码 ...
- 通过CSS3实现:鼠标悬停图片360度旋转效果
效果很好玩,代码很简单: 效果: 鼠标放置在图片上:360度顺时针旋转 鼠标离开图片:图片260度逆时针旋转 只要将下面代码拷贝过去,并将图片改成你想要的就可以看到效果 <!doctype ht ...
- Android实现图片相似度
Android实现图片相似度 最近公司有一个需求,就是希望能判断用户提交的照片是否是身份证的正面或者反面.可以通过预设一张拍摄清晰的身份证正面或者反面,来对比是否相似,那么问题就转化为如何计算两张图片 ...
- C#图片处理之:旋转图片90度的整数倍
原文:C#图片处理之:旋转图片90度的整数倍 旋转图片90的整数倍那真是太简单了. public static Bitmap KiRotate90(Bitmap img) ...
- 原生Js封装的产品图片360度展示
挺简单的一段程序,但是效果不错: 1.把需要展示的36张图片先预加载到浏览器缓存里 2.给展示图片的div添加方法 3.通过鼠标左右移动的像素转换图片 在线效果预览:http://jsfiddle.n ...
- 基于2-channel network的图片相似度判别
一.相关理论 本篇博文主要讲解2015年CVPR的一篇关于图像相似度计算的文章:<Learning to Compare Image Patches via Convolutional Neur ...
随机推荐
- OneForAll下载安装以及环境配置
python-3.9.7-amd64 OneForAll-master python安装以及插件安装 首先下载python解压到电脑c盘在c盘中创建一个工具文件夹,然后下载OneForAll-mast ...
- 使用Mybatis-Plus问题解答
我们使用一个新的框架难免会遇到各种问题,当然使用这款国产的优秀的Mybatis-Plus框架也不例外,下面我就给大家列举一下使用Mybatis-Plus可能遇到的一些问题,并做一下一一的解答. 1:如 ...
- spring-boot集成mybatis真的很简单吗?
在日常的后端开发中,使用mybatis作为DAO层的持久框架已经是惯例.但很多时候都是在别人搭好的框架中进行开发,对怎么搭建环境是一知半解,今天就来实践下. 一.集成分哪些步骤 来看下集成mybati ...
- Vue3 之 响应式 API reactive、 effect源码,详细注释
Vue3之响应式 API reactive. effect源码,详细注释 目录 一.实现响应式 API:reactive.shallowReactive.readonly.shallowReadonl ...
- Dubbo负载均衡策略之 一致性哈希
本文主要讲解了一致性哈希算法的原理以及其存在的数据倾斜的问题,然后引出解决数据倾斜问题的方法,最后分析一致性哈希算法在Dubbo中的使用.通过这篇文章,可以了解到一致性哈希算法的原理以及这种算法存在的 ...
- AR技术的应用与未来
目录 随着科技的不断进步,增强现实(AR)技术也在不断发展壮大.AR技术是一种通过计算机技术和传感器技术将虚拟信息融合到现实世界中的技术,可以为用户带来一种全新的.交互性更强的体验.本文将探讨AR技术 ...
- Linux下日志管理工具Logrotate
背景: 项目上的Nginx和Tomcat已经跑了大半年了,Nginx的access.log和error.log将近1G大小:Tomcat下的catalina.out日志经常跑到打不出日志然后进行手动移 ...
- Java反射源码学习之旅
1 背景 前段时间组内针对"拷贝实例属性是应该用BeanUtils.copyProperties()还是MapStruct"这个问题进行了一次激烈的battle.支持MapStru ...
- PostgreSQL 性能优化: EXPLAIN 使用教程
使用 EXPLAIN EXPLAIN基础 代价估计 启动开销 总开销 计划结点输出行数 计划结点输出行宽 执行统计 实际启动开销 实际总开销 实际输出行数 实际执行次数 I/O统计 共享块命中数 共享 ...
- 微信小程序 WXSS模板样式,全局和页面配置,网络请求
[黑马程序员前端微信小程序开发教程,微信小程序从基础到发布全流程_企业级商城实战(含uni-app项目多端部署)] https://www.bilibili.com/video/BV1834y1676 ...