前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python之对比两张图像的相似度

python之对比两张图像的相似度

作者头像
梦无矶小仔
发布2022-12-20 16:43:29
3.1K0
发布2022-12-20 16:43:29
举报

本着结合实际工作,实际落地并已应用的态度去码文。

python之对比两张图像的相似度

需求:在某个手机端项目中,有多个页面图片,但每个图片都做了相应的修改,由于这种图片非常多,高达上万张,每周有新的内容出现且需要回归。 在某些特定的节点,不允许相邻两张出现一模一样的图片,如果人去判定,非常非常耗时,于是需要自动化筛选,人工复核。

得,又接了一个非专业技能内的活,咋办,硬着头皮上?

那肯定不行,因为我不会;

但专业职场人怎么能说自己不会,不能!你得说,我可以学!

于是乎,我开始查找资料开始学习,找了一大圈,发现,AirTest里面就有这么一个API能够满足我的需求。拿来吧你,嘿嘿~

大致捋一下,所有页面图片通过自动化进行截图,在某些特定节点对图片命名中加入下划线作为区分,单独拿出特定节点的图片进行两两比较。

log展示

代码如下:[增加了日志追加写入并换行记录]

makeFolderResult方法为创建日志文件夹。

writeLog方法为将对比失败的图片名称写入日志中。[该日志将会直接写入目标图片路径根目录]

imageCompare方法为实际对比逻辑,阈值范围为0~1,越接近1表示图片相似度越高。

代码语言:javascript
复制
from airtest.aircv.cal_confidence import *

def makeFolderResult(imgPath, logName):
    logFloder = os.path.join(imgPath, f'图片对比结果')
    os.mkdir(logFloder)
    logPath = os.path.join(imgPath, f'图片对比结果/{logName}')
    return logPath

def wirteLog(msg, logPath):
    with open(logPath, "a+", encoding='utf-8') as f:
        f.write(msg)
        f.write("\n")

def imageCompare(imagePath, logPath,threshold:int):
    '''
    :param imagePath: 图片存放的路径
    :param logPath: 日志存放的路径
    :param threshold: 阈值,指定int类型
    :return: 
    '''
    needCompareImgDict = {}
    for root, dirs, files in os.walk(imagePath):
        for file in files:
            if "_" in file:
                key = str(file).split("_")[0]
                if key not in needCompareImgDict.keys():
                    needCompareImgDict[key] = [os.path.join(root, file)]
                else:
                    tempList = needCompareImgDict[key]
                    tempList.append(os.path.join(root, file))
                    needCompareImgDict[key] = tempList
    #### 遍历字典,将同个ID下的图片进行对比
    for imgs in needCompareImgDict.values():
        for i in range(len(imgs) - 1):
            img_1_path = imgs[i]
            img_2_path = imgs[i + 1]
            img_1_Name = img_1_path.split("\\")[-1]
            img_2_Name = img_2_path.split("\\")[-1]
            img1 = cv2.resize(cv2.imread(img_1_path), (370, 800)) # 图片尺寸根据实际图片写入
            img2 = cv2.resize(cv2.imread(img_2_path), (370, 800))
            confidence = cal_ccoeff_confidence(img1, img2)
            if confidence > threshold:
                writeMsg = f"【对比失败】,疑似 {img_1_Name}  与  {img_2_Name} 两张图片一致,相似度为:{round(confidence * 100, 2)}%"
                wirteLog(writeMsg, logPath)
                print(writeMsg)
            else:
                pass

if __name__ == '__main__':
    imagePath = "填入你图片存放的路径"
    logName = str(imagePath.split("\\")[-1]) + ".txt"
    logPath = makeFolderResult(imagePath, logName)
    imageCompare(imagePath, logPath)

cal_ccoeff_confidence这个API是核心,源码如下:

代码语言:javascript
复制
import cv2
import numpy as np
from .utils import img_mat_rgb_2_gray


def cal_ccoeff_confidence(im_source, im_search):
    """求取两张图片的可信度,使用TM_CCOEFF_NORMED方法."""
    # 扩展置信度计算区域
    im_source = cv2.copyMakeBorder(im_source, 10,10,10,10,cv2.BORDER_REPLICATE)
    # 加入取值范围干扰,防止算法过于放大微小差异
    im_source[0,0] = 0
    im_source[0,1] = 255

    im_source, im_search = img_mat_rgb_2_gray(im_source), img_mat_rgb_2_gray(im_search)
    res = cv2.matchTemplate(im_source, im_search, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    return max_val

有兴趣的小伙伴可以自己研究,没兴趣的如果遇到了,拿来就直接用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 梦无矶的测试开发之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • python之对比两张图像的相似度
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档