使用OpenCV和Python进行图像比对

原文参考这里
例如,我们想要对比下面两张图的不同
在这里插入图片描述
先安装scikit-imageimutils这两个库

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()

最后呈现的效果如下,没有原文那么完美,因为我是两幅图分别截图后保存,再调整两幅图的尺寸一致,与理想有偏差,无法保证除了右下角外所以地方都完全一致,还需改进。
在这里插入图片描述

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值