# OpenCV这么简单为啥不学——1.12、使用ssim函数对两张照片进行相似度分析

### 前言

1、研究代码（慢，不稳定，独立并与其他库不兼容）

2、耗费很高的商业化工具（比如Halcon, MATLAB+Simulink）

3、依赖硬件的一些特别的解决方案（比如视频监控，制造控制系统，医疗设备）这是如今的现状，而标准的API将简化计算机视觉程序和解决方案的开发，OpenCV致力于成为这样的标准API。

OpenCV致力于真实世界的实时应用，通过优化的C代码的编写对其执行速度带来了可观的提升，并且可以通过购买Intel的IPP高性能多媒体函数库（Integrated Performance Primitives）得到更快的处理速度。

### ssim函数

The structural similarity** (SSIM) index is a method for predicting the perceived quality of digital television and cinematic pictures, as well as other kinds of digital images and videos. The basic model was developed in the Laboratory for Image and Video Engineering(LIVE) at The University of Texas at Austin and further developed jointly with the Laboratory for Computational Vision (LCV) at New York University. Further variants of the model have been developed in the Image and Visual Computing Laboratory at University of Waterloo and have been commercially marketed.

### 图像相似度算法分类

1. 直方图比较法
2. 感知哈希算法
3. 内容特征法
4. 关键点匹配
5. SSIM（structural similarity，结构相似性）

## SSIM实操过程

### 2、环境搭建

# 数据处理
import numpy as np
# 图像操作
import cv2
# 使用scipy-convolve2d函数进行卷积
from scipy.signal import convolve2d

### 3、样式处理

def matlab_style_gauss2D(shape=(3, 3), sigma=0.5):
m, n = [(ss - 1.) / 2. for ss in shape]
y, x = np.ogrid[-m:m + 1, -n:n + 1]
h = np.exp(-(x * x + y * y) / (2. * sigma * sigma))
h[h < np.finfo(h.dtype).eps * h.max()] = 0
sumh = h.sum()
if sumh != 0:
h /= sumh
return h

### 4、过滤

def filter2(x, kernel, mode='same'):
return convolve2d(x, np.rot90(kernel, 2), mode=mode)

### 5、sim函数计算

def compute_ssim(im1, im2, k1=0.01, k2=0.04, win_size=11, L=255):
if not im1.shape == im2.shape:
raise ValueError("Input Imagees must have the same dimensions")
if len(im1.shape) > 2:
raise ValueError("Please input the images with 1 channel")
C1 = (k1 * L) ** 2
C2 = (k2 * L) ** 2
window = matlab_style_gauss2D(shape=(win_size, win_size), sigma=0.5)
window = window / np.sum(np.sum(window))
if im1.dtype == np.uint8:
im1 = np.double(im1)
if im2.dtype == np.uint8:
im2 = np.double(im2)
mu1 = filter2(im1, window, 'valid')
mu2 = filter2(im2, window, 'valid')
mu1_sq = mu1 * mu1
mu2_sq = mu2 * mu2
mu1_mu2 = mu1 * mu2
sigma1_sq = filter2(im1 * im1, window, 'valid') - mu1_sq
sigma2_sq = filter2(im2 * im2, window, 'valid') - mu2_sq
sigmal2 = filter2(im1 * im2, window, 'valid') - mu1_mu2
ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigmal2 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2))
return np.mean(np.mean(ssim_map))

### 6、图片拼接与保存

def img_show(similarity, img1, img2, name1, name2):
img1 = cv2.resize(img1, (520, 520))
img2 = cv2.resize(img2, (520, 520))
# 拼接两张图片
imgs = np.hstack([img1, img2])
path = "{0}".format('{0}VS{1}相似指数{2}%.jpg'.format(name1, name2, round(similarity, 2)))
cv2.imencode('.jpg', imgs)[1].tofile(path)
return path

### 7、调用过程

# 这里需要自己改一下
name1 = "图片1名称"
name2 = "图片2名称"
img1_path = '1.jpg'
img2_path = '2.jpg'
img1 = cv2.imread(img1_path)
img2 = cv2.imread(img2_path)
im1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
im2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
im1 = cv2.resize(im1, (520, 520))
im2 = cv2.resize(im2, (520, 520))
similarity = compute_ssim(im1, im2) * 100
if similarity == 100:
print("图片重复! 请重新上传图片")
sys.exit()
print(img_show(similarity, img1, img2, name1, name2))

### 总结

|
2月前
|

OpenCV这么简单为啥不学——1.8、threshold阈值0-4效果对照图
OpenCV这么简单为啥不学——1.8、threshold阈值0-4效果对照图
33 0
|
2月前
|

OpenCV这么简单为啥不学——1.3、图像缩放resize函数
OpenCV这么简单为啥不学——1.3、图像缩放resize函数
39 0
|
2月前
|

OpenCV这么简单为啥不学——1.13图片冷白皮(美白)处理
OpenCV这么简单为啥不学——1.13图片冷白皮(美白)处理
31 0
|
2月前
|

OpenCV这么简单为啥不学——1.11、蓝背景证件照替换白色或红色
OpenCV这么简单为啥不学——1.11、蓝背景证件照替换白色或红色
29 0
|
2月前
|

OpenCV这么简单为啥不学——1.10、addWeighted设置图片透明度
OpenCV这么简单为啥不学——1.10、addWeighted设置图片透明度
26 0
|
2月前
|

OpenCV这么简单为啥不学——1.9、cvtColor颜色空间转换(全色值效果演示)
OpenCV这么简单为啥不学——1.9、cvtColor颜色空间转换(全色值效果演示)
20 0
|
2月前
|

OpenCV这么简单为啥不学——1.7、实现OpenCV自带的七种形态学转换操作
OpenCV这么简单为啥不学——1.7、实现OpenCV自带的七种形态学转换操作
31 0
|
2月前
|

OpenCV这么简单为啥不学——1.6、图像旋转与翻转(rotate函数、imutils环境安装、imutils任意角度旋转)
OpenCV这么简单为啥不学——1.6、图像旋转与翻转(rotate函数、imutils环境安装、imutils任意角度旋转)
29 0
|
2月前
|

OpenCV这么简单为啥不学——1.5、解决putText中文乱码问题
OpenCV这么简单为啥不学——1.5、解决putText中文乱码问题
92 0
|
2月前
|

OpenCV这么简单为啥不学——1.4、基础标识绘制(绘制线line函数、rectangle函数绘制四边形、circle函数绘制圆形、putText函数绘制文字、putText绘制中文文字)
OpenCV这么简单为啥不学——1.4、基础标识绘制(绘制线line函数、rectangle函数绘制四边形、circle函数绘制圆形、putText函数绘制文字、putText绘制中文文字)
26 0