原文参考这里
例如,我们想要对比下面两张图的不同
先安装scikit-image
和imutils
这两个库
pip install scikit-image
pip install imutils
安装完成后在执行from skimage.measure import compare_ssim
时报错AttributeError: module 'skimage.measure' has no attribute 'compare_ssim'
因为自动安装了最新版本的scikit,新版本的skimage的内置程序被重置了,可以卸载scikit-image之后重装一个旧版本,如下pip install scikit-image==0.15.0
完整代码如下,注释均在代码里。
import argparse
import imutils
import cv2
from skimage.measure import compare_ssim
# # 建立两个命令行参数,-first和-second,用于两个图像的路径
# ap = argparse.ArgumentParser()
# ap.add_argument("-f", "--first", required=True, help = "first input image")
# ap.add_argument("-s", "--second", required=True, help= "second input image")
# args = vars(ap.parse_args())
imageA = cv2.imread('imageA.jpg')
imageB = cv2.imread('imageB.jpg')
rowA, colA, channelA = imageA.shape
rowB, colB, channelB = imageB.shape
print([rowA, colA, channelA], [rowB, colB, channelB])
# 将imageA和imageB处理成同样尺寸
imageB = cv2.resize(src = imageB, dsize=(colA, rowA))
# x, y, z = imageB.shape
# print([x,y,z])
#转为灰度图
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
garyB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
cv2.imshow('grayA', grayA)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 计算两个灰度图之间的结构相似性指数SSIM,得到score得分和差异图像diff
# score表示两个输入图像之间的结构相似性指数,可以落在[-1,1]范围内,值为1
# 是“完美匹配”
# diff包含实际“图像的差异”,我们希望可视化这个diff,diff当前表示[0,1]
# 范围内的浮点数据类型,首先将数组转换为[0,255]范围内的8位无符号整数,才能
# 进一步用openCV处理
(score, diff) = compare_ssim(X = grayA, Y = garyB, full=True)
diff = (diff * 255).astype("uint8")
print("SSIM:{}".format(score))
# 现在,让我们找到轮廓,以便我们可以在标识为“不同”的区域周围放置矩形
# 使用cv2.THRESH_BINARY_INV和cv2.THRESH_OTSU对diff进行阈值处理
thresh = cv2.threshold(src=diff, thresh = 0, maxval=255, type = cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# cnts为轮廓
cnts = imutils.grab_contours(cnts)
for c in cnts:
# compute the bounding box of the contour and then draw the
# bounding box on both input images to represent where the two
# images differ
(x, y, w, h) = cv2.boundingRect(c) #计算轮廓周围的边界框,矩形的宽度/高度为w/h
cv2.rectangle(imageA, (x,y), (x+w, y+h), (0, 0, 255), 2) #用x, y, w, h绘制红色矩形
cv2.rectangle(imageB, (x,y), (x+w, y+h), (0, 0, 255), 2)
# show the output images
cv2.imshow("Original", imageA)
cv2.imshow("Modified", imageB)
cv2.imshow("Diff", diff)
cv2.imshow("Thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
最后呈现的效果如下,没有原文那么完美,因为我是两幅图分别截图后保存,再调整两幅图的尺寸一致,与理想有偏差,无法保证除了右下角外所以地方都完全一致,还需改进。