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 ...
随机推荐
- flutter中使用pubspec.yaml更改package name
在flutter 项目中使用pubspec.yaml文件进行依赖资源相关配置是常有的事 但是刚发现它可以修改name来控制项目包名称,当初创建了不同的项目名git后还到每个文件里去修改import(麻 ...
- 代码随想录算法训练营Day12 栈与队列
代码随想录算法训练营 代码随想录算法训练营Day12 栈与队列| 239. 滑动窗口最大值 347.前 K 个高频元素 总结 239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的 ...
- 包含引用类型字段的自定义结构体,能作为map的key吗
1. 引言 在 Go 语言中,map是一种内置的数据类型,它提供了一种高效的方式来存储和检索数据.map是一种无序的键值对集合,其中每个键与一个值相关联.使用 map 数据结构可以快速地根据键找到对应 ...
- Access+Trunk 配置
实验拓扑 实验需求 按图示给各 PC 配置 IP 地址 在SW1和SW2上创建聚合组 PC1 与 PC3 属于 VLAN 10 : PC2 与 PC4 属于 VLAN 20 利用 Access 与 T ...
- 一致性hash算法原理及实践
大家好,我是蓝胖子,想起之前学算法的时候,常常只知表面,不得精髓,这个算法到底有哪些应用场景,如何应用在工作中,后来随着工作的深入,一些不懂的问题才慢慢被抽丝剥茧分解出来. 今天我们就来看看工作和面试 ...
- 【Azure 媒体服务】Azure Media Player 在Edge浏览器中不能播放视频问题的分析与解决
问题描述 使用Azure Media Service 制作视频点播服务,在客户端使用 Azure Media Player 播放器在 Edge 浏览器中播放视频时候遇见无法播放的问题: 错误信息: T ...
- expected unqualified-id on oneapi tbb12
230628-expected unqualified-id eton@230628 在编译supra基于debian12 Qt5.15 tbb12 libtbb12/stable,now 2021. ...
- 离线安装mysql报错解决方法:/usr/sbin/mysqld: error while loading shared libraries: libaio.so.1: cannot open sha --九五小庞
Linux:centos 7.6 64位 mysql:5.6使用离线方式安装:rpm -ivh --nodeps mysql* ,执行 systemctl start mysqld.service发现 ...
- python学习--解析网页
# -*- coding: utf-8 -*-"""Created on Thu Oct 17 14:04:21 2019 @author: DELL"&quo ...
- 使用 Sa-Token 实现不同的登录模式:单地登录、多地登录、同端互斥登录
一.需求分析 如果你经常使用腾讯QQ,就会发现它的登录有如下特点:它可以手机电脑同时在线,但是不能在两个手机上同时登录一个账号. 同端互斥登录,指的就是:像腾讯QQ一样,在同一类型设备上只允许单地点登 ...