由上一篇的思路我们可以定义以下的具体实现步骤

本篇将围绕窗口捕获、屏幕截图、截图切分讲述screen.py代码

环境描述C:\Users\SF>ver

Microsoft Windows [版本 10.0.18363.720]

C:\Users\SF>python --version

Python 3.7.6

启动方式 多标签版

分辨率 800x600

界面风格 暖风

窗口截图

主要是使用了PyQt5进行截图

hwnd_title = dict()

def get_all_hwnd(hwnd,mouse):

if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):

hwnd_title.update({hwnd:win32gui.GetWindowText(hwnd)})

def shot():

win32gui.EnumWindows(get_all_hwnd, 0)

mhxy_title = ''

for h,t in hwnd_title.items():

if t.startswith('梦幻西游 ONLINE'):

mhxy_title = t

print(mhxy_title)

hwnd = win32gui.FindWindow(None, mhxy_title)

app = QApplication(sys.argv)

desktop_id = app.desktop().winId()

screen= QApplication.primaryScreen()

img_desk = screen.grabWindow(desktop_id).toImage()

img_sc = screen.grabWindow(hwnd).toImage()

img_desk.save(img_desktop_path)

img_sc.save(img_sc_path)

print(f'img_desktop save to -> {os.path.abspath(img_desktop_path)}')

print(f'img_mhxy save to -> {os.path.abspath(img_sc_path)}')

if mhxy_title == '':

print('mhxy not start')

return False

return True

于是我们在路径

images

|- desktop.jpg

|- mhxy.jpg

得到一张全屏截图以及一张梦幻的窗口截图

截图切分

得到屏幕截图后,我们将对截图进行切分

战斗状态判断

因为进入战斗才会弹窗,所以首先对战斗状态进行判断

战斗状态的判断是依据了梦幻窗口最右侧战斗标识,不同的界面风格标识的颜色是不同的,我用的是暖风界面风格

战斗标识路径

images

|- flag

|- fighting_flag.jpg

截取相同区域的图片使用opencv与战斗标识进行相似性判断,如果相似度大于%95则判定为战斗状态

# 战斗截图

def fight_crop():

util.log_title('战斗标识截图')

return crop(c.img_sc_path,c.fighting_img_path,c.fight_shape)

# 是否在战斗

def is_fight():

util.log_title('状态判断')

rate = compare_image(c.fighting_flag_img_path,c.fighting_img_path)

if rate > 0.95:

print('战斗 状态')

return True

else:

print('非战斗 状态')

return False

# 相似性判断

def compare_image(path_image1, path_image2):

imageA = cv.imread(path_image1)

imageB = cv.imread(path_image2)

grayA = cv.cvtColor(imageA, cv.COLOR_BGR2GRAY)

grayB = cv.cvtColor(imageB, cv.COLOR_BGR2GRAY)

(score, diff) = structural_similarity(grayA, grayB, full=True)

print("SSIM: {}".format(score))

return score

# 裁剪

def crop(source_path,target_path,shape):

with Image.open(source_path) as img:

fighting_flag_img = img.crop(shape)

fighting_flag_img.save(target_path)

return True

截取战斗标识相同区域的路径为

images

|- sub

|- fighting.jpg

判断是否弹窗

接下来我们开始判断是否弹窗,目前见到的弹窗形式有两种,可以使用如下两种弹窗标识去匹配梦幻窗口

所以弹窗判断的思路如下

使用 OpenCV Template Matching 对梦幻窗口进行匹配,并返回最匹配(得分最高)的区域

def popup_sub_crop():

util.log_title('弹窗判断')

shape_dict = {}

for i in range(len(c.popup_flag_img_paths)):

shape,score = template_match(c.popup_flag_img_paths[i],c.img_sc_path)

shape_dict[shape] = (score,i)

print(shape_dict)

max_shape = max(shape_dict, key=shape_dict.get)

score,i = shape_dict[max_shape]

print(f'最大区域 {max_shape} 最终得分为 {score}' )

if score >=3 :

sub_shape = (

max_shape[0]+c.popup_move_shapes[i][0],

max_shape[1]+c.popup_move_shapes[i][1],

max_shape[2]+c.popup_move_shapes[i][2],

max_shape[3]+c.popup_move_shapes[i][3]

)

print(f'弹框区域 {sub_shape}')

return crop(c.img_sc_path,c.popup_sub_img_path,sub_shape)

print(f'没有弹框')

return False

def template_match(template_path,src_path):

img = cv.imread(src_path,0)

img2 = img.copy()

template = cv.imread(template_path,0)

w, h = template.shape[::-1]

methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED','cv.TM_CCORR',

'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']

shape_dict = {}

for meth in methods:

img = img2.copy()

method = eval(meth)

# Apply template Matching

res = cv.matchTemplate(img,template,method)

min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)

if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:

top_left = min_loc

else:

top_left = max_loc

bottom_right = (top_left[0] + w, top_left[1] + h)

# cv.rectangle(img,top_left, bottom_right, 255, 2)

# plt.subplot(121),plt.imshow(res,cmap = 'gray')

# plt.title('Matching Result'), plt.xticks([]), plt.yticks([])

# plt.subplot(122),plt.imshow(img,cmap = 'gray')

# plt.title('Detected Point'), plt.xticks([]), plt.yticks([])

# plt.suptitle(meth)

# plt.show()

shape = (top_left[0],top_left[1],bottom_right[0],bottom_right[1])

# print(shape)

if shape_dict.get(shape) == None:

shape_dict[shape] = 1;

else:

shape_dict[shape] = shape_dict[shape]+1

max_shape = max(shape_dict, key=shape_dict.get)

return max_shape,shape_dict[max_shape]

切出包含4个人物的大图

这个包含四个人物的图片宽高为360 x 120

def popup_sub_crop():

util.log_title('弹窗判断')

shape_dict = {}

for i in range(len(c.popup_flag_img_paths)):

shape,score = template_match(c.popup_flag_img_paths[i],c.img_sc_path)

shape_dict[shape] = (score,i)

print(shape_dict)

max_shape = max(shape_dict, key=shape_dict.get)

score,i = shape_dict[max_shape]

print(f'最大区域 {max_shape} 最终得分为 {score}' )

if score >=3 :

sub_shape = (

max_shape[0]+c.popup_move_shapes[i][0],

max_shape[1]+c.popup_move_shapes[i][1],

max_shape[2]+c.popup_move_shapes[i][2],

max_shape[3]+c.popup_move_shapes[i][3]

)

print(f'弹框区域 {sub_shape}')

return crop(c.img_sc_path,c.popup_sub_img_path,sub_shape)

print(f'没有弹框')

return False

路径如下

images

|- sub

|- pop_sub.jpg

再切出单个人物

单个人物宽高为90 x 120

def crop_4():

util.log_title('弹窗人物切分')

w = 90

h = 120

for i in range(len(c.crop_4_img_names)):

shape = (w*i, 0, w*(i+1), h)

crop(c.popup_sub_img_path,c.crop_4_img_paths[i],shape)

路径如下

images

|- sub

|- 1.jpg

|- 2.jpg

|- 3.jpg

|- 4.jpg

组合

于是我们将以上步骤组合起来

def task():

print()

if shot(): ## 截图

if image_check(c.img_sc_path,c.screen_size): ## 检查截图大小

fight_crop() ## 战斗标识截图

if is_fight(): ## 判断是否在战斗

if popup_sub_crop(): ## 弹窗识别 与 人物区域切出

if image_check(c.popup_sub_img_path,c.sub_size): ## 弹窗人物截图检查

crop_4() ## 弹窗人物切分

print()

return True

return False

if __name__ == '__main__':

task()

-------- 截图 ----------

梦幻西游 ONLINE - (xxxxxxx - xxxxx[xxxxx])

img_desktop save to -> d:\gitRepo\mhxy\images\desktop.jpg

img_mhxy save to -> d:\gitRepo\mhxy\images\mhxy.jpg

-------- 截图检查 ----------

size=(812, 663) ok

-------- 战斗标识截图 ----------

-------- 状态判断 ----------

SSIM: 0.9955642623257255

战斗 状态

-------- 弹窗判断 ----------

{(277, 221, 457, 234): (1, 0), (334, 223, 430, 237): (4, 1)}

最大区域 (334, 223, 430, 237) 最终得分为 4

弹框区域 (252, 252, 612, 372)

-------- 截图检查 ----------

size=(360, 120) ok

-------- 弹窗人物切分 ----------

回顾

到这里,窗口捕获、屏幕截图、截图切分部分就已经完毕,我们再来看一下进度

是不是胜利指日可待!

声明

本人无任何商业目的,仅用于学习和娱乐,源代码采用了AGPL3.0开源协议

本文为博主原创文章,任何人未经过博主同意不得转载

python 梦幻西游_tensorflow实践:梦幻西游人物弹窗识别(二)相关推荐

  1. 梦幻西游python验证成语_GitHub - rowliner/mhxy: tensorflow实践:梦幻西游人物弹窗识别...

    mhxy tensorflow实践:梦幻西游人物弹窗识别 环境描述 C:\Users\SF>ver Microsoft Windows [版本 10.0.18363.720] C:\Users\ ...

  2. python 梦幻西游_GitHub - BestBurning/mhxy: tensorflow实践:梦幻西游人物弹窗识别

    mhxy tensorflow实践:梦幻西游人物弹窗识别 环境描述 C:\Users\SF>ver Microsoft Windows [版本 10.0.18363.720] C:\Users\ ...

  3. 梦幻西游 python.dll_GitHub - 10508zhl/mhxy: tensorflow实践:梦幻西游人物弹窗识别

    mhxy tensorflow实践:梦幻西游人物弹窗识别 环境描述 C:\Users\SF>ver Microsoft Windows [版本 10.0.18363.720] C:\Users\ ...

  4. python提取人物特征_基于图像人物面部表情识别的特征提取优化方法与流程

    本发明涉及一种基于图像人物面部表情识别的特征提取优化方法,主要利用基于统计特征提取的二维主成分分析法和改进的粒子群算法优化图像矩阵的解,属于图像处理.模式识别和计算机视觉交叉技术应用领域. 背景技术: ...

  5. 实践 | Face-API实现人脸识别(附源代码)

    计算机视觉研究院 长按扫描维码关注 EDC.CV 计算机视觉研究院专栏 作者:Edison_G 参考face-api.js https://github.com/justadudewhohacks/f ...

  6. Python(TensorFlow框架)实现手写数字识别系统

    手写数字识别算法的设计与实现 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统.这是本人的本科毕业论文课题,当然,这个也是机器学习的基本问题 ...

  7. Python TensorFlow框架 实现手写数字识别系统

    手写数字识别算法的设计与实现 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统.这是本人的本科毕业论文课题,当然,这个也是机器学习的基本问题 ...

  8. python另存为_python+selenium修改“另存为”弹窗参数

    好多天没有按部就班地学习,这几天进行了高强度地探究实践: 上周天下午接了一个单子,客户目前重复做着一项工作,没有技术含量但特别消耗心理能量: 每天从固定网站上下载200多份文件,操作只是"查 ...

  9. 机器学习实践:动物图片识别-1

    机器学习实践:动物图片识别 1.实验描述 SVM(支持向量机)是一种常用的机器学习分类算法.使用HOG+SVM算法和OpenCV实现一个图片分类器,通过训练分类器,达到可以判断任意图片是否是动物的效果 ...

最新文章

  1. 数据结构与算法:08 Leetcode同步练习(三)
  2. 机器学习算法加强——回归
  3. SAP中采购订单状态与MRP的关系
  4. python xlsx 图片_实例11:用Python给Excel所有工作表添加图片
  5. 如何打造不怕被嗅探的3389登陆
  6. sql双表查询java代码_原生sql 多表查询
  7. JSP九大内置对象(转载)
  8. linux-04-磁盘命令+进程命令
  9. WPF 使用Console.Write打印信息到控制台窗口中
  10. Anaconda——复制Conda的虚拟环境
  11. knn算法java版_KNN算法的实现详解
  12. Qt Project Build error PRJ0019: 工具从Moc'ing xxx.h...
  13. C#图片处理之: 另存为压缩质量可自己控制的JPEG
  14. MIKE水动力笔记1_岸线及水深数据之依靠全球数据库资源提取的方法
  15. Dagger2的介绍和配置
  16. 华为S6720系列万兆交换机光模块解决方案
  17. 【计算机网络】(一):计算机网络+互联网基本知识
  18. [jzoj100047]【NOIP2017提高A组模拟7.14】基因变异
  19. 计算机科学读ms还是phd好,美研申请中怎样判断适合读硕士(MS)还是博士(PhD)?
  20. Android Studio 实战干货例程

热门文章

  1. 100部好看的校园喜剧片(可练习英文)+美国校园青春励志电影+25部口语练习电影+20部最浪漫电影
  2. ArcGIS 对地下管线进行分类标注
  3. 电磁兼容试验项目之谐波电流试验
  4. 基于同步坐标变换的谐波电流检测
  5. 当当网窘境:快电商容不下慢当当
  6. yum php fpm5.6,烂泥:yum安装php5.6
  7. glibc2.29+的off by null利用
  8. matlab pi表示,matlab中pi是什么意思
  9. Django Vue渲染动态数据(七)
  10. 安徽省计算机学校排名,2018“中国最好学科排名”公布 安徽这14所高校上榜