赞
踩
在做图像处理或者计算机视觉相关的项目的时候,很多时候需要我们对当前获得的图像和上一次的图像做相似性比对,从而找出当前图像针对上一次的图像的差异性和变化点,这需要用到OpenCV中的一些图像相似性和差异性的比对算法,在OpenCV-Python库中,有几种可以用来比较两幅图片差异的算法,以下是其中一些常用的算法:结构相似性指数,均方误差,峰值信噪比,结构相似性指数加权直方图。
win10 64位企业版系统
python版本:3.6.8 (x64)
opencv版本:3.4.2.16
IDE:pycharm2017(Ananconda 3.5.2)
特别说明:不同的OpenCV-Python库的版本,每种算法的名称会有一定的差别。
SSIM算法通过比较两幅图片的亮度、对比度和结构信息来评估它们的相似性。在OpenCV中,可以使用cv2.SIFT_create()
函数来计算两幅图片的SSIM指数。
代码示例:
- import cv2
- import numpy as np
-
- def ssim(img1, img2):
- # 将图像转换为灰度图像
- gray_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
- gray_img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
-
- # 计算图像的均值和方差
- mean1, mean2 = np.mean(gray_img1), np.mean(gray_img2)
- var1, var2 = np.var(gray_img1), np.var(gray_img2)
-
- # 计算协方差和SSIM指数
- cov = np.cov(gray_img1.flatten(), gray_img2.flatten())[0, 1]
- c1 = (0.01 * 255) ** 2
- c2 = (0.03 * 255) ** 2
- ssim = (2 * mean1 * mean2 + c1) * (2 * cov + c2) / ((mean1 ** 2 + mean2 ** 2 + c1) * (var1 + var2 + c2))
-
- return ssim
-
- # 读取两幅图像
- image1 = cv2.imread('0.jpg')
- image2 = cv2.imread('1.jpg')
-
- # 计算两幅图像的SSIM指数
- ssim_index = ssim(image1, image2)
-
- # 打印SSIM指数
- print("SSIM Index:", ssim_index)
输入两幅“0.jpg”和“1.jpg”的图像,运行即可以得到比对的结果:
在高版本的OpenCV中,自带了创建SSIM对象的函数,可以直接调用:
- import cv2
-
- # 读取两幅图像
- image1 = cv2.imread('image1.png')
- image2 = cv2.imread('image2.png')
-
- # 将图像转换为灰度图像
- gray_image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
- gray_image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
-
- # 创建SSIM对象
- ssim = cv2.SIFT_create()
-
- # 计算两幅图像的SSIM指数
- ssim_index = ssim.compare(gray_image1, gray_image2)
-
- # 打印SSIM指数
- print("SSIM Index:", ssim_index)
在上述代码中,首先使用cv2.imread()
函数读取两幅图像。然后,使用cv2.cvtColor()
函数将图像转换为灰度图像,因为SSIM算法只适用于灰度图像。接下来,创建SSIM对象,并使用其compare()
方法计算两幅图像的SSIM指数。最后,打印SSIM指数。
请注意,cv2.SIFT_create()
函数在该示例中用于创建SSIM对象,但它实际上是用于创建尺度不变特征变换(Scale-Invariant Feature Transform, SIFT)对象的函数。在OpenCV-Python库中,SIFT对象也可以用于计算SSIM指数。
MSE算法计算两幅图片每个像素之间的差异,并计算它们的平均值。MSE值越小,表示两幅图片越相似。在OpenCV中,可以使用cv2.absdiff()
和cv2.mean()
函数来计算两幅图片的MSE值。
- import cv2
- import numpy as np
-
- def mse(img1, img2):
- # 计算两个图像的差异
- diff = cv2.absdiff(img1, img2)
- diff_squared = diff ** 2
-
- # 计算均方误差
- mse = np.mean(diff_squared)
-
- return mse
-
- # 读取两幅图像
- image1 = cv2.imread('0.jpg')
- image2 = cv2.imread('1.jpg')
-
- # 调整图像的大小,使其具有相同的尺寸
- image1 = cv2.resize(image1, (image2.shape[1], image2.shape[0]))
-
- # 计算两幅图像的均方误差
- mse_value = mse(image1, image2)
-
- # 打印均方误差
- print("MSE:", mse_value)
在上述代码中,mse()
函数计算了两幅图像的均方误差。首先,使用cv2.absdiff()
函数计算两个图像之间的差异,并将差异值的平方存储在diff_squared
中。然后,使用np.mean()
函数计算差异平方的平均值,得到均方误差。最后,返回均方误差值。
请注意,在比较两个图像之前,我们还调整了它们的大小,以确保它们具有相同的尺寸。这是因为均方误差是基于像素级别的比较,需要确保两幅图像具有相同的大小。
PSNR算法通过计算两幅图片的MSE值,并将其转换为对数尺度,来评估它们的相似性。PSNR值越大,表示两幅图片越相似。在OpenCV中,可以使用cv2.PSNR()
函数来计算两幅图片的PSNR值。
- import cv2
- import numpy as np
-
- def psnr(img1, img2):
- # 计算两个图像的均方误差
- mse = np.mean((img1 - img2) ** 2)
-
- # 计算峰值信噪比
- psnr = 10 * np.log10((255 ** 2) / mse)
-
- return psnr
-
- # 读取两幅图像
- image1 = cv2.imread('0.jpg')
- image2 = cv2.imread('1.jpg')
-
- # 调整图像的大小,使其具有相同的尺寸
- image1 = cv2.resize(image1, (image2.shape[1], image2.shape[0]))
-
- # 将图像转换为浮点数类型
- image1 = image1.astype(np.float64)
- image2 = image2.astype(np.float64)
-
- # 计算两幅图像的峰值信噪比
- psnr_value = psnr(image1, image2)
-
- # 打印峰值信噪比
- print("PSNR:", psnr_value)
在上述代码中,psnr()
函数计算了两幅图像的峰值信噪比。首先,计算两个图像之间的均方误差(MSE),即差异的平方的平均值。然后,使用np.log10()
函数计算峰值信噪比,其中255
是像素值的最大值。最后,返回峰值信噪比值。请注意,为了计算峰值信噪比,我们将图像的数据类型转换为浮点数类型,以避免溢出。这是因为峰值信噪比是基于像素级别的比较,需要进行数值计算。
SSIM-WH算法通过将SSIM指数和直方图相似性组合起来,来评估两幅图片的相似性。在OpenCV中,可以使用cv2.compareHist()
函数来计算两幅图片的直方图相似性。
- import cv2
-
- def compare_hist(img1, img2):
- # 将图像转换为HSV颜色空间
- img1_hsv = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
- img2_hsv = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
-
- # 计算图像的直方图
- hist1 = cv2.calcHist([img1_hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
- hist2 = cv2.calcHist([img2_hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
-
- # 归一化直方图
- cv2.normalize(hist1, hist1, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
- cv2.normalize(hist2, hist2, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
-
- # 计算直方图相似性
- similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
-
- return similarity
-
- # 读取两幅图像
- image1 = cv2.imread('0.jpg')
- image2 = cv2.imread('1.jpg')
-
- # 调整图像的大小,使其具有相同的尺寸
- image1 = cv2.resize(image1, (image2.shape[1], image2.shape[0]))
-
- # 计算两幅图像的相似性
- similarity = compare_hist(image1, image2)
-
- # 打印相似性度量值
- print("Similarity:", similarity)
在上述代码中,compare_hist()
函数比较了两幅图像的相似性。首先,将图像转换为HSV颜色空间。然后,使用cv2.calcHist()
函数计算图像的直方图。这里使用了2D直方图,其中通道0和1表示H(色调)和S(饱和度)通道。接下来,使用cv2.normalize()
函数对直方图进行归一化处理,以便进行比较。最后,使用cv2.compareHist()
函数计算直方图之间的相似性度量。cv2.HISTCMP_CORREL
参数表示使用相关性作为相似性度量。返回的相似性度量值越接近1,表示两幅图像越相似。请注意,这只是一种比较图像相似性的方法之一。根据具体的需求,可能需要使用其他方法来比较图像的相似性
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。