SSIM---结构相似性算法(OpenCV+Python)

一.SSIM算法原理

SSIM(structural similarity),结构相似性,是一种衡量两幅图像相似度的指标。SSIM算法主要用于检测两张相同尺寸的图像的相似度、或者检测图像的失真程度。原论文中,SSIM算法主要通过分别比较两个图像的亮度,对比度,结构,然后对这三个要素加权并用乘积表示。

在这里插入图片描述
常数𝑪𝟏, 𝑪𝟐, 𝑪𝟑是为了避免当分母为 0 时造成的不稳定问题。
𝝁𝒙为均值, 𝝈𝒙 为方差, 𝝈𝒙𝒚 表示协方差。
在这里插入图片描述
在这里插入图片描述

二.skimage.metrics包下的SSIM算法

  • 函数原型:
def structural_similarity(*, im1, im2,
                         win_size=None, gradient=False, data_range=None,
                         multichannel=False, gaussian_weights=False,
                         full=False, **kwargs)
  • 参数:
    :Ndarray,输入图像
参数含义
im1,im2Ndarray,输入图像
win_sizeint or none,optional,滑动窗口的边长,必为奇数,默认值为7, 当gaussian_weights=True时,滑动窗口的大小取决于sigma
gradientbool, optional,若为True,返回相对于im2的梯度
data_rangefloat,optional,图像灰度级数,图像灰度的最小值和最大可能值,默认情况----根据图像的数据类型进行估计
multichannelbool, optional,值为True时将 img.shape[-1] 视为图像通道数,对每个通道单独计算,取平均值作为相似度
gaussian_weightsbool, optional,高斯权重,值为True时,平均值和方差在空间上的权重为归一化高斯核 宽度sigma=1.5
fullbool, optional,值为true时,返回完整的结构相似性图像
  • 其他参数:
    use_sample_covariance:若为True,则通过N-1归一化协方差,N是滑动窗口内的像素数
    K1,K2: float, 算法参数,默认值K1=0.01,K2=0.03
    sigma: float,当gaussian_weights=True时,决定滑动窗口大小

  • 返回值:
    mssim—平均结构相似度
    grad—结构相似性梯度 (gradient=True)
    S—结构相似性图像(full=True)

下面是通过调用skimage.metrics包下的SSIM算法,结合OpenCV中的阈值分割及轮廓提取算法,找出两幅图像的差异。

import cv2
import imutils
from skimage.metrics import structural_similarity
import time
from skimage import filters, img_as_ubyte
import numpy as np

start = time.time()
# 读入图像,转为灰度图像
src = cv2.imread('C:/Users/Hedgehog/Desktop/right.jpg')
img = cv2.imread('C:/Users/Hedgehog/Desktop/left.jpg')
grayA = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 计算两个灰度图像之间的结构相似度
(score, diff) = structural_similarity(grayA, grayB, win_size=101, full=True)
diff = (diff * 255).astype("uint8")
cv2.namedWindow("diff", cv2.WINDOW_NORMAL)
cv2.imshow("diff", diff)
print("SSIM:{}".format(score))

# 找到不同的轮廓以致于可以在表示为 '不同'的区域放置矩形
# 全局自适应阈值分割(二值化),返回值有两个,第一个是阈值,第二个是二值图像
dst = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cv2.namedWindow("threshold", cv2.WINDOW_NORMAL)
cv2.imshow('threshold', dst)
# findContours找轮廓,返回值有两个,第一个是轮廓信息,第二个是轮廓的层次信息(“树”状拓扑结构)
# cv2.RETR_EXTERNAL:只检测最外层轮廓
# cv2.CHAIN_APPROX_SIMPLE:压缩水平方向、垂直方向和对角线方向的元素,保留该方向的终点坐标,如矩形的轮廓可用4个角点表示
contours, hierarchy = cv2.findContours(dst.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
newimg = np.zeros(dst.shape, np.uint8)  # 定义一个和图像分割处理后相同大小的黑色图
# drawContours画轮廓,将找到的轮廓信息画出来
cv2.drawContours(newimg, contours, -1, (255, 255, 255), 1)
cv2.namedWindow("contours", cv2.WINDOW_NORMAL)
cv2.imshow('contours', newimg)
# cnts = cnts[0] if imutils.is_cv3() else cnts[0]    取findContours函数的第一个返回值,即取轮廓信息

# 找到一系列区域,在区域周围放置矩形
for c in contours:
    (x, y, w, h) = cv2.boundingRect(c)  # boundingRect函数:计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的
    cv2.rectangle(src, (x, y), (x + w, y + h), (0, 255, 0), 2)  # rectangle函数:使用对角线的两点pt1,pt2画一个矩形轮廓
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 画矩形的图, pt1, pt2,(对角线两点的坐标), 矩形边框的颜色,矩形边框的粗细

end = time.time()
print(end - start)
# 用cv2.imshow 展现最终对比之后的图片
cv2.namedWindow("right", cv2.WINDOW_NORMAL)
cv2.imshow('right', src)
cv2.namedWindow("left", cv2.WINDOW_NORMAL)
cv2.imshow('left', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 15
    点赞
  • 166
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: Python OpenCV可以用来进行图像对比。图像对比是指将两个或多个图像进行比较,以确定它们之间的相似性或差异性。在Python OpenCV中,可以使用cv2.matchTemplate()函数来进行图像对比。该函数将一个模板图像与另一个输入图像进行比较,并返回一个匹配图像,其中每个像素表示该像素在输入图像中的匹配程度。可以使用不同的匹配方法来进行比较,例如平方差匹配、相关性匹配和归一化互相关匹配。 ### 回答2: PythonOpenCV为我们提供了非常强大而灵活的工具来进行图像对比。图像对比是指找出两幅图像之间的差异,比较它们之间的相似度和差异。这种技术在许多应用程序中都得到了广泛的应用,例如计算机视觉、医学图像处理、自动拍摄机器人以及安全系统等。 常见的图像对比方法有均方误差、峰值信噪比、结构相似度等。这些方法的实现都很容易使用PythonOpenCV来完成,我们可以快速的进行图像对比分析。 下面介绍一些常见的图像对比方法: 1.均方误差(MSE):使用MSE方法来计算两幅图像之间的相似度。我们可以将两幅图像的每个像素都作为像素值的计划来计算 MSE。这通常用于图像压缩和复原应用程序中。 2.峰值信噪比(PSNR):PSNR是一种基于均方误差的方法,可用于评估两幅图像之间的相似性。PSNR把MSE的值转换为分贝单位,这种方法可用于评估图像质量。 3.结构相似度(SSIM):结构相似度是一种常用的图像对比方法,它使用 块相似性结构相似性来确定两幅图像之间的相似性SSIM经常用于比较失真的图像,如JPEG压缩图像。 总之,PythonOpenCV提供了一种强大的方式来分析图像,比较像素之间的相似性,找出两幅图像之间的差异。我们可以选择不同的图像对比方法来完成这一任务,视图获得最佳的结果。 ### 回答3: Python OpenCV图像对比主要是用来比较两张或多张图像之间的相似程度,通常用于图像匹配。在实际的图像处理中,图像对比有很多应用,例如目标检测、图像识别、人脸识别等。 首先需要了解的是图像对比的基本概念——图像相似度。在计算图像相似度时,可以计算两张图像的像素点之间的欧式距离。欧式距离是欧几里得距离的简称,是指在两点之间连接直线的最短距离。在图像中,欧式距离就是像素点之间灰度值的差值,因为像素点的灰度值越相似,则它们之间的欧式距离越小。 在Python OpenCV中,可以使用cv2.matchTemplate()函数来计算两张图像之间的相似度。该函数主要是通过模板匹配算法,来在一幅图像中查找和另一幅模板图像最相似的位置。具体实现方法就是将模板图像在另一幅图像中滑动,然后计算每个位置处两幅图像的相似度,最终找到相似度最高的位置。 除了cv2.matchTemplate()函数外,在Python OpenCV中还有很多其他的图像对比算法,例如SIFT(尺度不变特征变换)算法、SURF(加速稳健特征)算法、ORB(旋转不变特征)算法等。这些算法各具特点,应根据实际应用需求进行选择。 总之,Python OpenCV图像对比是一个重要的图像处理技术,能够在实现目标检测、图像匹配、图像识别等应用中发挥重要作用。通过该技术,可以快速、准确地查找相似图像,并为后续图像处理工作提供有力支持。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值