python比较两张截图相似度

需求
让电脑自动判断是否收到微信消息
思路
截图1:清屏
截图2:发送信息之后
计算两张截图的相似度
实现
截图,处理像素点并哈希化,如果两个图片不同哈希位数大于设置的阈值,则认为两张图片不相同,即:收到了微信消息

直接上代码吧,思路很简单!

#图片相似度比较
from PIL import Image
import time
from PIL import ImageGrab
import os
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


#计算图片hash值
def get_hash(srcimg,dstimg):
    print("当前图像的尺寸为:",dstimg.size)
    hh = srcimg.height
    ww = srcimg.width
    img = dstimg.resize((hh,ww), Image.ANTIALIAS).convert('L')#灰度处理

    print("转换图像尺寸为:",hh,ww)
    avg = sum(list(img.getdata())) /(hh*ww)  # 计算像素平均值
    s = ''.join(map(lambda i: '0' if i < avg else '1', img.getdata()))  # 每个像素进行比对,大于avg为1,反之为0
    print("一共有{}个像素点".format(len(s)))
    t=''.join(map(lambda j: '%x' % int(s[j:j+4], 2), range(0, hh*ww, 4)))#将二进制转换为16进制
    return t


#比较图片hash值
def hamming(target,x1,y1,x2,y2):
    target_path = target.split("-")[0]
    target_name = target.split("-")[1]
    # 防止截全屏的页面没反应过来
    time.sleep(1)
    global root_dir
    app_action_img = root_dir + '/APP_Action_Icons/' + target_path + "/" + target_name + '.png'
    zui=False#预设返回结果为False
    try:
        #根据给定的位置进行截图
        time.sleep(2)
        img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
        time.sleep(2)
        print("截取该区间的屏幕:({},{})~({},{})".format(x1, y1, x2, y2))
        ##保存截屏位置
        Screenshot_img = root_dir + '/Screen_Shots/Test_Screen_shots/similarimg.jpg'
        img.save(Screenshot_img)
        ##等待图片保存
        time.sleep(0.5)
        #对图像哈希
        im1 = Image.open(app_action_img)
        im2 = Image.open(Screenshot_img)
        hash1=get_hash(im1,im1)
        hash2=get_hash(im1,im2)
        print("哈希值一共有{}位".format(len(hash1)))
        hh = im1.height
        ww = im1.width
        #>=98%的相似度才可以认为两个图片相同
        n = hh * ww // 200
        print("如果有{}个哈希值不同则认为两个图片不同".format(n))
        assert len(hash1) == len(hash2)
        sum=0
        for ch1, ch2 in zip(hash1, hash2):
            if ch1!=ch2:
                sum+=1
        print("不同的哈希值有{}位".format(sum))
        #比较两个hash值不同的位数,n为阈值,大于该阈值则认为两者是不同的图片
        zui= False if sum >n else True
        indenti = (hh * ww // 4 - sum) / (hh * ww // 4)

        #如果第一次没有匹配成功,则再给他一个机会
        if zui==False:
            print("两秒钟之后重新截图...")
            time.sleep(2)
            time.sleep(2)
            img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
            time.sleep(2)
            print("截取该区间的屏幕:({},{})~({},{})".format(x1, y1, x2, y2))
            ##保存截屏
            Screenshot_img = root_dir + '/Screen_Shots/Test_Screen_shots/similarimg_2.png'
            img.save(Screenshot_img)
            ##等待图片保存
            time.sleep(0.5)

            im1 = Image.open(app_action_img)
            im2 = Image.open(Screenshot_img)
            hash1 = get_hash(im1, im1)
            hash2 = get_hash(im1, im2)
            print("哈希值一共有{}位".format(len(hash1)))
            hh = im1.height
            ww = im1.width
            n = hh * ww // 200
            print("如果有{}个哈希值不同则认为两个图片不同".format(n))
            assert len(hash1) == len(hash2)
            sum = 0
            for ch1, ch2 in zip(hash1, hash2):
                if ch1 != ch2:
                    sum += 1
            print("不同的哈希值有{}位".format(sum))
            # 比较两个hash值不同的位数,n为阈值,大于该阈值则认为两者是不同的图片

            zui = False if sum > n else True
            indenti=(hh*ww//4-sum)/(hh*ww//4)
    except Exception as e:
        print("相似度对比失败,请重试!", e)
    else:
        print("相似度对比成功,相似度为:",indenti)
    return zui



print(hamming('企业微信-聊天框',313,63,1915,685))

清屏截屏:
python比较两张截图相似度_第1张图片

发送信息后截屏为:
python比较两张截图相似度_第2张图片

运行结果为:

截取该区间的屏幕:(313,63)~(1915,685)
当前图像的尺寸为: (1302, 622)
转换图像尺寸为: 622 1302
一共有809844个像素点
当前图像的尺寸为: (1602, 622)
转换图像尺寸为: 622 1302
一共有809844个像素点
哈希值一共有202461位
如果有4049个哈希值不同则认为两个图片不同
不同的哈希值有8914位
两秒钟之后重新截图...
截取该区间的屏幕:(313,63)~(1915,685)
当前图像的尺寸为: (1302, 622)
转换图像尺寸为: 622 1302
一共有809844个像素点
当前图像的尺寸为: (1602, 622)
转换图像尺寸为: 622 1302
一共有809844个像素点
哈希值一共有202461位
如果有4049个哈希值不同则认为两个图片不同
不同的哈希值有8501位
相似度对比成功,相似度为: 0.9580116664444016
False

Process finished with exit code 0

你可能感兴趣的:(python业务类)