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 ...
随机推荐
- 代码随想录算法训练营Day21 二叉树
代码随想录算法训练营 代码随想录算法训练营Day21 二叉树| 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先 530.二叉搜索树的最小绝对差 题目链接:5 ...
- 为什么会出现 setTimeout 倒计时误差
setTimeout 倒计时误差的出现主要与 JavaScript 的事件循环机制和计时器的执行方式有关. 在 JavaScript 中,事件循环是用于管理和调度代码执行的机制.setTimeout ...
- WinUI(WASDK)使用HelixToolkit加载3D模型并进行项目实践
前言 本人之前开发了一个叫电子脑壳的上位机应用,给稚晖君ElectronBot开源机器人提供一些功能,但是由于是结合硬件才能使用的软件,如果拥有硬件的人员太少,就会导致我的软件没什么人用,于是我就想着 ...
- .net 项目静态文件自动压缩打包
打包工具选型 在 ASP.NET MVC 时代,我们常使用 BundleCollection 设置需要打包压缩的 js 和 css 文件,运行时框架会自动处理打包压缩过程并将最终结果传入响应. ASP ...
- 深入理解Go语言接口
1. 引言 接口是一种定义了软件组件之间交互规范的重要概念,其促进了代码的解耦.模块化和可扩展性,提供了多态性和抽象的能力,简化了依赖管理和替换,方便进行单元测试和集成测试.这些特性使得接口成为构建可 ...
- 前端vue uni-app基于uQRCode封装简单快速实用全端二维码生成插件
快速实现基于uQRCode封装简单快速实用全端二维码生成插件; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12677 效果图 ...
- 前端下拉框组件CCDropDownFilter下拉框 筛选框 仿美团下拉筛选框
快速实现下拉框 筛选框 仿美团下拉筛选框, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12421 效果图如下: # 下拉框使用方法 ...
- 老生常谈:值类型 V.S. 引用类型
我在面试的时候经常会问一个问题:"谈谈值类型和引用的区别".对于这个问题,绝大部分人都只会给我两个简洁的答案:"值类型分配在栈中,引用类型分配在堆中",&quo ...
- EDP转LVDS屏转接板方案芯片CS5211替代CH7511B电路设计
CS5211替代CH7511B电路设计: CS5211用于设计DP转LVDS转换器,DP转LVDS控制板,DP转LVDS转接板等产品设计,其性能和参数可以替代与兼容PS8622,PS8625,CH75 ...
- 行行AI人才直播第9期:销氪副总裁陈摩西《AI在企业服务领域的商业化应用设计思路》
人工智能 (AI) 正在颠覆几乎所有行业,并正在改变我们开展业务的方式.近年来,SaaS 行业一直是受影响最大的行业之一,人工智能在其指数级增长中发挥着至关重要的作用.随着 AI 技术逐渐落地和市场认 ...