不要傻乎乎的去找不同了,一起来用代码完成“找不同”游戏吧

简介: 不要傻乎乎的去找不同了,一起来用代码完成“找不同”游戏吧

项目需求


  相信大家不少的人曾经都玩过找不同游戏的,今天想趁热打铁,做一个找不同游戏的“辅助”来进行自动找不同。先来介绍找不同游戏的操作逻辑:


1. 登录游戏网页端,全屏显示便于清晰查看不同点;


2. 画面中显示两张相似的图像,这两张图像只存在部分地方存在差异;


3. 点击存在差异的地方即认可为完成了“找不同”任务


  介绍完游戏的操作逻辑,我们根据操作逻辑进行“自动找不同”程序设计实现上述逻辑:


1. 截取当前游戏画面(固定);


2. 分别锚定两张相似图像并切割下来(由于游戏画面固定,出现图像的位置也会固定);


3. 对两张相似的图像进行处理得到不同位置的位置,并输出中心点坐标。




需求分析


  实现“找不同”一件很难的事情,程序设计的前两个需求并不是很难,通过前面两个辅助的制作,可以通过pyautogui.screenshot() 和 pymouse 可以实现屏幕画面的截取和鼠标的移动点击;通过OpenCvd的切割可以实现相似图的切割。较为难实现的是找到不同的位置,本文也将重点分析如何找到不同!


  网上流传较为广的是一种遍历两张图像的像素,当像素不一样的时候输出此时的位置。这里我就不阐述它的逻辑了。我将按照如下的几种方案实现找不同任务:


1. 对裁剪下来的两张图像进行灰度化后做差得到结果进行二值化;


2. 使用图像匹配法完成“找不同”


3. 遍历像素实现




实施验证


  今日时间有限,先做个“丐版”的找不同。从技术实现的角度有限解决核心部分,实现“有无”的难题。我们提前将两张相似的图像截取下来:

image.png

image.png

使用作差法实现:

import cv2
img_1 = cv2.imread("1.png") # Slicing to crop the image
img_2 = cv2.imread("2.png")
img_1 = cv2.cvtColor(img_1,cv2.COLOR_BGR2GRAY)
img_2 = cv2.cvtColor(img_2,cv2.COLOR_BGR2GRAY)
img3 = img_1 - img_2
ret, img3 = cv2.threshold(img3, 50, 255,  cv2.THRESH_BINARY_INV)
cv2.imshow("a", img3)
cv2.waitKey(0)
复制代码

image.png

使用遍历像素实现:

import cv2
img_1 = cv2.imread("1.png") # Slicing to crop the image
img_2 = cv2.imread("2.png")
img_11 = cv2.cvtColor(img_1, cv2.COLOR_BGR2GRAY)
img_22 = cv2.cvtColor(img_2, cv2.COLOR_BGR2GRAY)
width,height = img_11.shape
for i in range(width):
    for j in range(height):
        x = img_11[i][j]
        y = img_22[i][j]
        if abs(x - y) > 30:
            img_1[i][j] = [0, 0, 0]
cv2.imshow("result", img_1)
cv2.waitKey(0)
复制代码

image.png



图像匹配法


图像匹配法是借用某位大神的代码,结果供大家参考一下:


import cv2
import numpy as np
from matplotlib import pyplot as plt
import argparse
def matchAB(fileA, fileB):
    # 读取图像数据
    imgA = cv2.imread(fileA)
    imgB = cv2.imread(fileB)
    # 转换成灰色
    grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
    grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)
    # 获取图片A的大小
    height, width = grayA.shape
    # 取局部图像,寻找匹配位置
    result_window = np.zeros((height, width), dtype=imgA.dtype)
    for start_y in range(0, height - 100, 10):
        for start_x in range(0, width - 100, 10):
            window = grayA[start_y:start_y + 100, start_x:start_x + 100]
            match = cv2.matchTemplate(grayB, window, cv2.TM_CCOEFF_NORMED)
            _, _, _, max_loc = cv2.minMaxLoc(match)
            matched_window = grayB[max_loc[1]:max_loc[1] + 100, max_loc[0]:max_loc[0] + 100]
            result = cv2.absdiff(window, matched_window)
            result_window[start_y:start_y + 100, start_x:start_x + 100] = result
    # 用四边形圈出不同部分
    _, result_window_bin = cv2.threshold(result_window, 30, 255, cv2.THRESH_BINARY)
    _, contours, _ = cv2.findContours(result_window_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    imgC = imgA.copy()
    for contour in contours:
        min = np.nanmin(contour, 0)
        max = np.nanmax(contour, 0)
        loc1 = (min[0][0], min[0][1])
        loc2 = (max[0][0], max[0][1])
        cv2.rectangle(imgC, loc1, loc2, 0, 2)
    plt.subplot(1, 3, 1), plt.imshow(cv2.cvtColor(imgA, cv2.COLOR_BGR2RGB)), plt.title('A'), plt.xticks([]), plt.yticks(
        [])
    plt.subplot(1, 3, 2), plt.imshow(cv2.cvtColor(imgB, cv2.COLOR_BGR2RGB)), plt.title('B'), plt.xticks([]), plt.yticks(
        [])
    plt.subplot(1, 3, 3), plt.imshow(cv2.cvtColor(imgC, cv2.COLOR_BGR2RGB)), plt.title('Answer'), plt.xticks(
        []), plt.yticks([])
    plt.show()
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--source_image',
        type=str,
        default='1.png',
        help='source image'
    )
    parser.add_argument(
        '--target_image',
        type=str,
        default='2.png',
        help='target image'
    )
    FLAGS, unparsed = parser.parse_known_args()
    matchAB(FLAGS.source_image, FLAGS.target_image)
复制代码

image.png



相关文章
|
安全 Java Go
推荐几款免费实用的第五代图形验证码
推荐几免费实用的图形验证码,主要形式有滑动拼图、文字点选、语序点选、字体识别、空间推理、智能随机等。
1403 0
推荐几款免费实用的第五代图形验证码
|
11月前
|
Ubuntu Unix Linux
Linux网络文件系统NFS:配置与管理指南
NFS 是 Linux 系统中常用的网络文件系统协议,通过配置和管理 NFS,可以实现跨网络的文件共享。本文详细介绍了 NFS 的安装、配置、管理和常见问题的解决方法,希望对您的工作有所帮助。通过正确配置和优化 NFS,可以显著提高文件共享的效率和安全性。
2449 7
|
Kubernetes 网络协议 Ubuntu
Kubeadm 快速搭建 k8s v1.19.1 集群(Ubuntu Server 20.04 LTS)
安装准备工作安装环境要求:角色 实验环境 生产环境 操作系统 master cpu/内存:2 Core/2G cpu/内存:2 Core/4G linux 内核 4.4+ node cpu/内存:1 Core/2G cpu/内存:4 Core/16G linux 内核 4.4+ 备注 Node:应根据需要运行的容器数量进行配置; Linux 操作系统基于 x86_64 架构的各种 Linux 发行版...
1566 2
Kubeadm 快速搭建 k8s v1.19.1 集群(Ubuntu Server 20.04 LTS)
|
安全 Windows
win10系统:局域网下共享文件夹设置,解决其他电脑访问不成功问题
这篇文章是关于如何在Windows 10系统下设置局域网共享文件夹,并解决其他电脑访问不成功的问题的详细指南。
42860 7
win10系统:局域网下共享文件夹设置,解决其他电脑访问不成功问题
|
Serverless 数据安全/隐私保护 前端开发
大模型代码能力体验报告之贪吃蛇小游戏《一》:Claude.ai篇 - 生成、预览和快速部署的serverless一条龙
本文介绍了通过Claude.ai生成并优化Web版贪吃蛇游戏的过程,展示了其强大的代码生成功能及用户友好的界面设计。从初始版本的快速生成到根据用户反馈调整游戏速度,再到提供多种实用工具如文件管理、版本控制和一键部署,Claude.ai不仅是一个代码助手,更像是一个全面的serverless开发平台。文中还呼吁国内厂商关注此类技术的发展。
616 2
|
算法 Python
SciPy 教程 之 SciPy 优化器 1
SciPy 的 optimize 模块提供了多种最优化算法,用于解决寻找函数最小值、方程的根等问题。与 NumPy 不同,SciPy 可以处理非线性方程的根。通过 `optimize.root` 函数,只需提供方程和初始猜测值即可求解。例如,求解方程 `x + cos(x)` 的根,可以使用 `root` 函数轻松实现。
142 0
|
开发工具 git
成功解决:Svnion not found. installat
这篇文章分享了作者在使用VSCode进行SVN版本控制时遇到的一个问题,即SVN插件提示找不到`svn.exe`的问题。原因是在安装SVN时没有选择客户端工具,导致没有`svn.exe`文件。文章提供了解决方案,包括重新安装SVN时选择客户端工具,并在VSCode的`setting.json`文件中配置SVN的路径。
成功解决:Svnion not found. installat
|
安全
神秘代码
这是针对IDEA 2023.2.4的破解码,允许用户免费激活软件。该破解码包含详细的授权信息,能绕过付费使用限制,实现全面功能解锁。注意,使用此类破解码可能违反相关软件使用协议,并存在安全风险。建议通过官方渠道获取正版软件。
10477 0
cocos 2.4*项目实战笔记及源码分享 —— 飞机大战小游戏
cocos 2.4*项目实战笔记及源码分享 —— 飞机大战小游戏
475 0
|
存储 算法 数据处理
逻辑结构与存储结构的区别
**逻辑结构**是指数据对象中数据元素之间的逻辑关系,它描述了数据的组织方式。这种结构不涉及数据在内存中的具体存储方式,而是更多关注数据元素之间的逻辑关系,如线性关系、树形关系、图形关系等。 **存储结构**也称为物理结构,是指数据的实际存储在计算机内存中的组织方式。它关心如何将数据存放在计算机的内存或其他存储设备中,以便有效地访问和修改。存储结构通常包括顺序存储结构、链式存储结构等。
458 0