• 封校大学生在宿舍无聊玩起图像大找茬——一个关于游戏的练手小项目(一起领略Python脚本的风采吧)


    ???一个帅气的boy,你可以叫我
    ?? 个人主页:的个人主页
    ???如果对你有帮助的话希望三连???支持一下博主

    图像大找茬

    前言

    在一个月黑风高的夜晚,我的舍友小许摇起我来,面色惊恐地说道:“快来帮我,我要不行了o(╥﹏╥)o”。我连忙起身,问到他你怎么了,他把我拉到他电脑面前,一脸凝重的说道:这两张图片我找不出第五个不同的地方。我上来…就给他个大B兜,睡觉。凄凄惨惨戚戚,独留一人守空房…


    基础知识

    1. 首先我们要想分清两种图片的不同就要想起它——灰度图。
    2. 其次我们找到一个可以获取不同页面句柄的库实时截取图片(这里不采用抓包)
    3. PyQt5设计页面

    图片找茬

    原图:

    灰度图使用skimage库可以轻松解决pip install scikit-image,同时安装pip install opencv-python以显示图片。

    imageA = cv2.imread("./first.png")
    imageB = cv2.imread("./second.png")
    grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
    grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
    
    • 1
    • 2
    • 3
    • 4

    扩展:用到了SSIM原理,也可以叫他结构相似性指数,是一种衡量两幅图像相似度的指标。

    #调用ssim函数
    from skimage.metrics import structural_similarity
    #返回三个值
    mssim, grad , S = structural_similarity(grayA, grayB, gradient=True,full=True)
    '''
    mssim:float
    图像上的平均结构相似性指数。
    
    grad:ndarray
    im1 和 im2 [2]之间结构相似性的梯度。这仅在梯度设置为 True 时返回。
    
    S:ndarray
    完整的 SSIM 图像。这仅在full设置为 True 时返回。
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    可以打印mssim数值观察ssim指数,此指数越高说明越相似

    但是需要注意的是 SSIM返回的ndarray里面的值为[0, 1]的float型,而OpenCV的[0, 255]为uint8型,用如下转换:

    grad= (grad* 255).astype("uint8")
    
    • 1

    grad对应图片:

    然后用cv2中图像阈值处理threshold函数去寻找轮廓,然后用imutils.grab_contours返回cnts中的countors(轮廓),然后用cv2.boundingRect获取边界框位置,直接用cv2.rectangle画出方框

    thresh = cv2.threshold(S, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
    cnts = imutils.grab_contours(cnts)
    
    • 1
    • 2

    threshold函数寻找到的轮廓:

    for c in cnts:
        #获取边界框位置
       (x, y, w, h) = cv2.boundingRect(c)
       cv2.rectangle(imageA, (x, y), (x + w, y + h), (0, 0, 255), thickness = 4)
       cv2.rectangle(imageB, (x, y), (x + w, y + h), (0, 0, 255), thickness = 4)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    最后打印图片保存即可。
    源码

    #Image_Compare
     from skimage.metrics import structural_similarity
    import imutils
    import cv2
    import argparse
    def Make_picture() -> object:
        parser = argparse.ArgumentParser(description="查找茬图像输入")
        parser.add_argument("-f","--first",default=False,help="first image")
        parser.add_argument("-s","--second",help="first image")
        args = vars(parser.parse_args())
        imageA = cv2.imread("./first.png")
        imageB = cv2.imread("./second.png")
        #灰度图
        grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
        grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
        #计算两幅图像之间的结构相似性指数(SSIM),确保返回差异图像
        (mssim, grad ,S) = structural_similarity(grayA, grayB, full=True,gradient=True)
        S = (S * 255).astype("uint8")
        thresh = cv2.threshold(S, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
        cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours(cnts)
        for c in cnts:
            (x, y, w, h) = cv2.boundingRect(c)
            cv2.rectangle(imageA, (x, y), (x + w, y + h), (0, 0, 255), thickness = 4)
            cv2.rectangle(imageB, (x, y), (x + w, y + h), (0, 0, 255), thickness = 4)
        cv2.waitKey(0)
        cv2.imwrite(filename="Find_Different.png", img=imageB)
    #测试时解开注释
    #Make_picture()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    抓取句柄图片

    需要安装pip install pywin32,这个库可以完成根据自己电脑打开的程序抓取所需句柄(也就是已经打开的任意程序)
    具体操作:打开qq游戏大厅中的大家来找茬小游戏,咳咳,找个座位坐下,进入游戏前点开程序,然后开始游戏后点击开始!!开始检测!!!十图场乱杀!!!!!

    #PyQt5_catchWindows.py
    import win32gui
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtGui import *
    import sys
    from Image_Compare import  Make_picture
    from PIL import Image # 导入PIL库
    import win32con
    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)})
            hwnd_title.update({hwnd:win32gui.GetWindowText(hwnd)})
            win32gui.EnableWindow(hwnd,True)
        #print(win32gui.IsWindow(hwnd))
    def Get_Windows():
    #通过将句柄依次传递给应用程序定义的回调函数,枚举屏幕上的所有顶级窗口。
        win32gui.EnumWindows(get_all_hwnd, 0)
        for h,t in hwnd_title.items():
            if t != '':
               print(h,t)
            if t == '大家来找茬':
                hwnd = win32gui.FindWindow(None, t)
                #返回屏幕坐标中窗口的矩形
                b = win32gui.GetWindowRect(hwnd)
                screen = QApplication.primaryScreen()
                img1 = screen.grabWindow(hwnd,549,311,383,288).toImage()
                img1.save("first.png", "png")
                img2 = screen.grabWindow(hwnd, 92, 311, 383, 288).toImage()
                img2.save("second.png", "png")
                clsname = win32gui.GetClassName(hwnd)
                title = win32gui.GetWindowText(hwnd)
                return img1,img2
            #print(clsname, title)
    def Start():
        img1,img2 = Get_Windows()
        Make_picture()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    GUI界面搭建

    按上述操作完成后打开界面如下

    #Pyqt_UI.py
    import sys
    from PyQt5 import QtWidgets, QtCore, QtGui
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    import PyQt5_catchWindows
    class picture(QWidget):
        def __init__(self):
            super(picture, self).__init__()
    
    
            self.setWindowTitle("显示图片")
    
            self.label = QLabel(self)
            self.label.setText("生成图像框")
            self.label.setFixedSize(383,288)
            self.label.move(10, 10)
    
            self.label.setStyleSheet("QLabel{background:white;}"
                                     "QLabel{color:rgb(300,300,300,120);"
                                     "font-size:70px;font-weight:bold;"
                                     "font-family:黑体;}"
                                     )
    
            btn = QPushButton(self)
            btn.setText("开始检测")
            print(1)
            btn.move(160, 330)
            btn.clicked.connect(self.openimage)
    
        def openimage(self):
            PyQt5_catchWindows.Start()
            imgName = "Find_Different.png"
            jpg = QtGui.QPixmap(imgName).scaled(self.label.width(), self.label.height())
            self.label.setPixmap(jpg)
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        my = picture()
        my.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    纯纯辅助神器,喜欢的朋友们可以去玩一玩哦???求一键三连。

    项目地址

  • 相关阅读:
    【零基础一看就会】Python爬虫从入门到应用(上)
    【Javascript】编写⼀个函数,排列任意元素个数的数字数组,按从⼩到⼤顺序输出
    2022年月饼包装出新规啦!一起来看看今年的月饼包装有多好看吧!
    Java项目打包的可执行jar 文件部署到云服务器,并请求接口
    多维时序 | MATLAB实现TCN时间卷积神经网络多变量时间序列预测
    C语言验证哥德巴赫猜想(ZZULIOJ1093:验证哥德巴赫猜想(函数专题))
    GitHub价值1w的Java最新面试宝典(附答案解析)被我弄到手了
    信息安全-应用安全-蚂蚁集团软件供应链安全实践
    opencv中边缘检测的方法
    MySQL删除数据库(DROP DATABASE语句)
  • 原文地址:https://blog.csdn.net/qq_46416934/article/details/125402116