需求
让电脑自动判断是否收到微信消息
思路
截图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))
运行结果为:
截取该区间的屏幕:(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