本宝宝又回来了 Python做个简单的游戏辅助
我在玩QQ游戏 比如大家来找茬的时候 眼力不是很好 经常找不到,但是又好奇 这我没找到的位置都在哪里呢?所以我做个辅助帮我把两幅图的像素相减,再把得到的噪点值粘回去到某幅图上,总体流程列出来就是
- 找到”大家来找茬”游戏窗口句柄,窗口提到最前好截图
- 切分左右两张图片,切成小图后根据像素区间分布找出差值比较大的矩形标出
- OpenCv的两张图像像素相减,去噪
- 显示结果,把步骤2的标识图片+步骤3的像素差噪图合在一起
Ok 大致就是这样 showCodeTime
# -*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
### 系统自带的模块
from datetime import datetime
import ImageGrab
import shutil
import math
import os
### 可能需要额外安装的模块部分
# 自动化模块
import win32gui
import win32con
# 图片处理模块
import ImageDraw
import Image
# OpenCv模块
import cv2
import numpy as np### 全局变量
# 当前文件夹路径
CUR_DIR = os.getcwd()# 获得句柄
game_hwnd = win32gui.FindWindow(None, u"大家来找茬")
# 强行显示界面后才好截图
win32gui.ShowWindow(game_hwnd, win32con.SW_RESTORE)
# 将游戏窗口提到最前
win32gui.SetForegroundWindow(game_hwnd)
# 裁剪得到部分主要图片,作为处理素材
game_rect = win32gui.GetWindowRect(game_hwnd)
src_image = ImageGrab.grab((game_rect[0] + 9, game_rect[1] + 190, game_rect[2] - 9, game_rect[1] + 190 + 450))# # 将得到的图片保存下来 后面如果要改进也好当素材
sucai = os.path.join(CUR_DIR, 'sucai')
ICount = len(os.listdir(sucai))
if not os.path.exists(sucai):os.makedirs(sucai)
save_path = os.path.join(sucai, datetime.now().strftime("%Y_%m_%d_%H_%M_%S_")+str(ICount))+'.png'
src_image.save(save_path)"""
### 这部分代码主要是拿素材来测试结果的
file_name = "full.png"
file_name = os.path.join(sucai, os.listdir(sucai)[11])
src_image = Image.open(file_name)
"""def compare(image_a, image_b):"""用来获得两图比较的数值差:返回两图的差异值 返回两图红绿蓝差值万分比之和image_a : 图a, image_b : 图b"""histogram_a = image_a.histogram()histogram_b = image_b.histogram()if len(histogram_a) != 768 or len(histogram_b) != 768:return# 红 差值比率red_a = 0red_b = 0for i in xrange(0, 256):red_a += histogram_a[i + 0] * ired_b += histogram_b[i + 0] * idiff_red = 0max_red = red_a + red_bif red_a + red_b > 0:diff_red = abs(red_a - red_b) * 10000 / max_red# 绿 差值比率green_a = 0green_b = 0for i in xrange(0, 256):green_a += histogram_a[i + 256] * igreen_b += histogram_b[i + 256] * idiff_green = 0 max_green = green_a + green_bif green_a + green_b > 0:diff_green = abs(green_a - green_b) * 10000 / max_green# 蓝 差值比率blue_a = 0blue_b = 0for i in xrange(0, 256):blue_a += histogram_a[i + 512] * iblue_b += histogram_b[i + 512] * idiff_blue = 0max_blue = blue_a + blue_bif blue_a + blue_b > 0:diff_blue = abs(blue_a - blue_b) * 10000 / max_bluemSum = max_red + max_green + max_blueresult = 0if mSum > 0:# 自定义权重计算result = ( max(red_a, red_b) + max(green_a, green_b) + max(blue_a, blue_b) ) - ( min(red_a, red_b) + min(green_a, green_b) + min(blue_a, blue_b) )result = result * 10000 / (max_red + max_green + max_blue)# 颜色白的图片 集体像素都比较高 所以总像素深度可以作为一个参考量result = result * math.pow( (max_red + max_green + max_blue) / 100000.0 , 0.7 )return resultdef pic_sub(dest, s1, s2, threshod):"""这个函数主要是计算两张图片的相熟差的dest : 结果存贮矩阵, s1 : 图1, s2 : 图2, threshod : 阈值"""for x in range(dest.shape[0]):for y in range(dest.shape[1]):if (s2[x,y] > s1[x,y]):dest[x,y] = s2[x,y] - s1[x,y]else:dest[x,y] = s1[x,y] - s2[x,y]if (dest[x,y] < threshod):dest[x,y] = 0else:dest[x,y] = 255### 创建一个类 找茬
class findCha(object):def __init__(self, src_image):super(findCha, self).__init__()# 传入要分析的窗口图片self.src_image = src_imageself.init()def init(self):# 这里主要是找到左右两张用来比对的图片 由于是我个人娱乐所用 暂时没考虑不同电脑的分辨率left_box = (84, 124, 464, 408)right_box = (541, 124, 541 + 380, 408)# 切开找到左右两图self.image_left = self.src_image.crop(left_box)self.image_right = self.src_image.crop(right_box)# 两张图片保存到本地media文件夹下 为何要保存了 因为我用了像素分布比较+OpenCV的两张图像素相减 这里保存的图就是给cv用的self.saveMedia()# OpenCV 找到两张图像素相减的差异self.bitDiff()# 根据像素分布区间差 用画矩阵的形式标识出self.drawRect(1, 1500)# 展示图片保存结果self.saveImage()def saveMedia(self):""" 找到要找的茬 两张图片保存到本地media文件夹下 """media = os.path.join(CUR_DIR, 'media')if os.path.exists(media):shutil.rmtree(media)os.makedirs(media)self.image_left_path = os.path.join(media, 'img_left.png')self.image_left.save(self.image_left_path)self.image_right_path = os.path.join(media, 'image_right.png')self.image_right.save(self.image_right_path)def bitDiff(self):""" 两张图片像素相减 去燥后的图片 """threshod = 20s1 = cv2.imread(self.image_left_path, 0)s2 = cv2.imread(self.image_right_path, 0)# 初始空矩阵 用于存储相减结果emptyimg = np.zeros(s1.shape, np.uint8)pic_sub(emptyimg, s1, s2, threshod)# 保存 二值图像,两者的差值图片self.bit_diff_path = os.path.join(CUR_DIR, 'media', 'bit_diff.png')cv2.imwrite(self.bit_diff_path, emptyimg)def drawRect(self, multiple, low_limit):"""在图片上画矩阵作为标识multiple : 图片切分大小倍数, low_limit : 根据像素区间差 差量大于这个下限值要显示"""img_width = 380img_height = 284# 横向切割为几张图片div_x = int(19 * multiple)# 纵向切割图片div_y = int(15 * multiple)# 切成小图的长宽值width = int(math.ceil(img_width / div_x))height = int(math.ceil(img_height / div_y))# 设置画板draw = ImageDraw.Draw(self.image_right)for col in xrange(0, div_x + 1):for row in xrange(0, div_y + 1):clip_box = (col * width, row * height, (col + 1) * width, (row + 1) * height)# 左右两边裁剪出相应位置小图来比对clip_image_left = self.image_left.crop(clip_box)clip_image_right = self.image_right.crop(clip_box)clip_diff = compare(clip_image_left, clip_image_right)if clip_diff > low_limit:draw.rectangle(clip_box)# 消除滑板del drawdef saveImage(self):""" 显示结果和保存图片 """toImage = Image.new('RGBA', (380, 284*3))toImage.paste(self.image_left, (0, 0))# 左右图片像素相减后的噪点图bit_diff_img = Image.open(self.bit_diff_path).convert(self.image_left.mode)bit_diff_img = bit_diff_img.resize(self.image_left.size)img = Image.blend(self.image_right, bit_diff_img, 0.7)toImage.paste(img, (0, 284))toImage.paste(self.image_right, (0, 284*2))toImage.show()if __name__ == '__main__':findCha(src_image)
大致就是这样 现在想做成标识出差异的图片 之后去燥做得更好一些再做成自动点击自动和自动下一局的
部分结果显示