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

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

项目需求


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


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



相关文章
|
3月前
流星雨代码
流星雨代码
|
6月前
|
存储 安全 Java
写出漂亮代码的45个小技巧(下)
大家好,我是三友~~ 不知道大家有没有经历过维护一个已经离职的人的代码的痛苦,一个方法写老长,还有很多的if else ,根本无法阅读,更不知道代码背后的含义,最重要的是没有人可以问,此时只能心里默默地问候这个留坑的兄弟。。
写出漂亮代码的45个小技巧(下)
最近特火的爱心代码来了
最近因为一部《点燃我温暖你》的电视剧而爆火的爱心代码不会还有人不会制作吧。
最近特火的爱心代码来了
李峋的爱心代码
《点燃我温暖你》中李峋的爱心代码
137 0
李峋的爱心代码
|
SQL 人工智能 前端开发
无代码的未来
随着无代码技术越来越成熟,很多web应用已经可以基于无代码平台进行开发。本文分析了4个最流行的无代码平台,并梳理了无代码行业今后可能的发展方向。
373 0
无代码的未来
|
前端开发 C++
这几行代码,真的骚!
这几行代码,真的骚!
这几行代码,真的骚!
|
数据可视化 开发工具 git
如何给你的代码祝寿?
前段时间 alibaba/x-render 突破 3K Star,一直寻思着怎么给开源社区贡献的同学做一个小礼物来“祝寿”,然后就想到了之前玩过的 gource 和 avconv 这两个库(参数不熟悉可查文档,此外不多加解释),前者用于处理提交日志可视化,后者用于视频处理。
|
程序员 数据库
【评论】好代码不值钱
导读: 原文来自geekm.ag 上一篇《 Good code is cheap code》,由国内整理编译《好代码不值钱》。作者认为好的程序员和伟大的程序员之间的区别就在于伟大的程序员理解他们的模式。
850 0