如何查找两张图像的差异 即使其中一张内物体存在轻微旋转
图像差异查找与高亮实现方案
第一步:前置预处理(避免黑边干扰)
对齐后的图像存在黑边属于无效区域,需要先处理避免影响差异检测结果:
- 对对齐后的图像做二值化,提取非零像素的最小外接矩形,裁掉黑边区域,再统一缩放到和主图像完全相同的尺寸
- 若对齐精度不足,可以先做一次亚像素级的微调对齐,避免像素偏移带来的假差异
第二步:三种常用差异检测方法
方法1:像素差法(最直接,适合明显差异)
直接对两张同尺寸图做逐像素相减,对差值做阈值过滤后得到差异掩码:
- 灰度图场景:计算两张灰度图的绝对差值,大于阈值的像素即为差异区域
- 彩色图场景:可以分通道做差后合并,或者转LAB颜色空间做明度和色度的差异计算,对模糊的检测更敏感
方法2:结构相似性SSIM检测(适合检测模糊、轻微形变)
SSIM可以量化两张图的结构相似程度,返回的差异图中数值越低的区域就是差异越大的位置,比像素差法更适合检测轻微模糊这类不明显的差异:
- 调用结构相似性计算接口,设置返回完整差异矩阵
- 对差异矩阵取反后二值化,即可得到模糊、形变类的差异区域
方法3:特征点匹配残差法(适合匹配错误排查)
如果是匹配结果出错,可以提取两张图的SIFT/SURF特征点做匹配,计算匹配点的重投影误差,误差超过阈值的位置就是匹配错误的区域,能定位到对齐失败的局部位置。
第三步:差异高亮可视化
得到差异掩码后,有几种高亮方式可选:
- 蒙版叠加:把差异区域用半透明红色蒙版叠加到主图或者对齐后的图上,差异位置一目了然
- 热力图:把差异的大小映射为从蓝到红的热力图,叠加到原图上,能直观看到差异的严重程度,模糊越严重的区域颜色越深
- 边界框标注:对差异掩码做轮廓检测,给每个连通的差异区域画矩形框或者轮廓线,还可以标注差异的大小、类型
示例核心代码(Python+OpenCV+Skimage)
import cv2 import numpy as np from skimage.metrics import structural_similarity as ssim # 读取图像 master = cv2.imread("Master.png") aligned = cv2.imread("aligned_result.jpg") # 统一尺寸 aligned = cv2.resize(aligned, (master.shape[1], master.shape[0])) # 转灰度图 gray_master = cv2.cvtColor(master, cv2.COLOR_BGR2GRAY) gray_aligned = cv2.cvtColor(aligned, cv2.COLOR_BGR2GRAY) # 计算SSIM差异 (score, diff) = ssim(gray_master, gray_aligned, full=True) diff = (diff * 255).astype("uint8") # 二值化得到差异掩码 thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] # 找差异轮廓 contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] # 高亮标注差异 for c in contours: area = cv2.contourArea(c) if area > 10: # 过滤噪点 x,y,w,h = cv2.boundingRect(c) cv2.rectangle(aligned, (x,y), (x+w,y+h), (0,0,255), 2) # 保存结果 cv2.imwrite("diff_result.jpg", aligned)
内容的提问来源于stack exchange,提问作者mihir lakhani
相关产品推荐
相关产品推荐

