0x00 方案概述,技术栈

深度学习训练模型:YOLOv5框架

图像识别:OpenCV

编程语言:python

IDE:Pycharm

运行环境:Pytorch+CUDA+Anaconda

这篇博客我不会特别具体的讲操作流程,更注重用到的一些函数和库之类的

实现方法大概是:实时截取屏幕,然后通过比对模型来识别截取图片上的CT,T阵营人物。然后获取坐标,传给我们自己写的函数,然后调用操控鼠标的库,实现开枪。

0x01 YOLOv5框架

什么叫yolov5?其实就是 You Only Look Once 意思是这个框架简单到你看一次,或者上手试着用一次你就会了。

V5和V4没有递进关系,两个是独立的框架,不存在哪个最好哪个不好。

首先我们从GitHub上把yolov5的框架clone下来,为了方便,我们使用Ceaser的Csgo-yolov5模型,全是中文备注,更方便我们去训练模型

制作数据集,打标签:

配置环境:

要在本地先查看你的CUDA版本

然后根据一系列信息在官网安装pytorch

首先先在csgo游戏中截取大量游戏过程中的图片

打标签有两种方式:

1:Make Sense在线打标签

2:python的一个库labelimg 使用pip install安装

使用train.py等待完成安装

0x02 实现屏幕截取

api-生成窗口cv2.namedWindow

    cv2.namedWindow('csgo-detect', cv2.WINDOW_NORMAL)

函数原型:

void nameWindow(const string& winname,int flags = WINDOW_AUTOSIZE) ;

arg1:新建的窗口的名称。自己随便取

arg2:窗口的标识,一般默认为WINDOW_AUTOSIZE

  • WINDOW_AUTOSIZE 窗口大小自动适应图片大小,并且不可手动更改。(上面图1就是使用的它)

  • WINDOW_NORMAL 用户可以改变这个窗口大小(上面图2就是使用的它)

  • WINDOW_OPENGL 窗口创建的时候会支持OpenGL

api-改变窗口尺寸cv2.resizeWindow

    cv2.resizeWindow('csgo-detect', re_x // 3, re_y // 3)

arg1:窗口名

arg2,arg3:位置

api-展示窗口cv2.imshow

cv2.imshow('csgo-detect', img)

arg1:窗口名

arg2:图片

api-等待函数cv2.waitKey

    if cv2.waitKey(1) & 0xFF == ord('q'):        cv2.destroyAllWindows()        break

刚开始只知道加上cv2.waitKey之后cv2.imshow就可以显示图像了

为什么cv2.imshow之后要跟cv2.waitkey

imshow的作用是在GUI里显示一幅图像,但是它有个特点我们没有太注意,就是它的持续时间。

测试后可得

waitkey控制着imshow的持续时间,当imshow之后不跟waitkey时,相当于没有给imshow提供时间展示图像,所以只有一个空窗口一闪而过。添加了waitkey后,哪怕仅仅是cv2.waitkey(1),我们也能截取到一帧的图像。所以cv2.imshow后边是必须要跟cv2.waitkey的。

imshow源码里的注释

This function should be followed by cv::waitKey function which displays the image for specified . milliseconds. Otherwise, it won't display the image.

这个函数之后应接cv2.waitKey函数来显示指定图像。否则,它不会显示图像。

为什么要这么麻烦的设计

This function is the only method in HighGUI that can fetch and handle events, so it needs to be

这个函数是HighGUI窗口中唯一的获取和处理事件的方法,因此它必须存在

cv2.waitKey(1) & 0xFF == ord(‘q’) 的作用

在linux上使用waitkey有时会出现waitkey返回值超过了(0-255)的范围的现象,通过&0xff来解决这个现象

ord是把字符转换成ascii码

cv2.waitkey和time.sleep的区别

有人写在代码时把waitkey当sleep用过,你会发现有时waitkey并不起作用。

官方解释:The function only works if there is at least one HighGUI window created and the window is active

翻译:这个函数只有在至少一个HighGUI窗口存在的情况下才会起作用。

waitkey的延时机制是有条件的,必须在它之前创造HighGUI窗口它才会起作用。而time.sleep是无条件的延时机制。

api-关闭所有窗口destroyAllWindows()

cv2.destroyAllWindows()

关闭窗口并取消分配任何相关的内存使用。对于一个简单的程序,实际上不必调用这些函数,因为退出时操作系统会自动关闭应用程序的所有资源和窗口

win32系列

使用win32gui.SetWindowPos置顶窗口

api-寻找窗口win32gui.Findwindow

hwnd = win32gui.FindWindow(None,'windowname')

arg1:窗口类名

arg2:窗口标题

api-获得窗口属性cv2.getWindowImageRect

CVRECT = cv2.getWindowImageRect('windowname')

arg1:窗口标题

api-窗口位置设置win32gui.SetWindowPos

win32gui.SetWindowPos(hwnd,win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)

函数原型

BOOL SetWindowPos(HWN hWnd,HWND hWndlnsertAfter,int X,int Y,int cx,int cy,UNIT.Flags)

功能:该函数改变一个子窗口,弹出式窗口式顶层窗口的尺寸,位置和Z序。子窗口,弹出式窗口,及顶层窗口根据它们在屏幕上出现的顺序排序、顶层窗口设置的级别最高,并且被设置为Z序的第一个窗口

arg1:窗口句柄

arg2:在z序中的位于被置位的窗口前的窗口句柄。该参数必须为一个窗口句柄,或下列值之一:

HWND_BOTTOM:将窗口置于Z序的底部。如果参数hWnd标识了一个顶层窗口,则窗口失去顶级位置,并且被置在其他窗口的底部。

HWND_DOTTOPMOST:将窗口置于所有非顶层窗口之上(即在所有顶层窗口之后)。如果窗口已经是非顶层窗口 则该 标志不起作用。

HWND_TOP:将窗口置于Z序的顶部。

HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置

x:以客户坐标指定窗口新位置的左边界。

Y:以客户坐标指定窗口新位置的顶边界。

cx:以像素指定窗口的新的宽度。

cy:以像素指定窗口的新的高度

uFlags:窗口尺寸和定位的标志。该参数可以是下列值的组合:

SWP_ASNCWINDOWPOS:如果调用进程不拥有窗口,系统会向拥有窗口的线程发出需求。这就防止调用线程在其他线程处理需求的时候发生死锁。

SWP_DEFERERASE:防止产生WM_SYNCPAINT消息。

SWP_DRAWFRAME:在窗口周围画一个边框(定义在窗口类描述中)。

SWP_FRAMECHANGED:给窗口发送WM_NCCALCSIZE消息,即使窗口尺寸没有改变也会发送该消息。如果未指定这个标志,只有在改变了窗口尺寸时才发送WM_NCCALCSIZE。

SWP_HIDEWINDOW;隐藏窗口。

SWP_NOACTIVATE:不激活窗口。如果未设置标志,则窗口被激活,并被设置到其他最高级窗口或非最高级组的顶部(根据参数hWndlnsertAfter设置)。

SWP_NOCOPYBITS:清除客户区的所有内容。如果未设置该标志,客户区的有效内容被保存并且在窗口尺寸更新和重定位后拷贝回客户区。

SWP_NOMOVE:维持当前位置(忽略X和Y参数)。

SWP_NOOWNERZORDER:不改变z序中的所有者窗口的位置。

SWP_NOREDRAW:不重画改变的内容。如果设置了这个标志,则不发生任何重画动作。适用于客户区和非客户区(包括标题栏和滚动条)和任何由于窗回移动而露出的父窗口的所有部分。如果设置了这个标志,应用程序必须明确地使窗口无效并区重画窗口的任何部分和父窗口需要重画的部分。

SWP_NOREPOSITION;与SWP_NOOWNERZORDER标志相同。

SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。

SWP_NOSIZE:维持当前尺寸(忽略cx和Cy参数)。

SWP_NOZORDER:维持当前Z序(忽略hWndlnsertAfter参数)。

SWP_SHOWWINDOW:显示窗口。

返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。若想获得更多错误消息,请调用GetLastError函数。

备注:如果设置了SWP_SHOWWINDOW和SWP_HIDEWINDOW标志,则窗口不能被移动和改变大小。如果使用SetWindowLoog改变了窗口的某些数据,则必须调用函数SetWindowPos来作真正的改变。使用下列的组合标志:SWP_NOMOVEISWP_NOSIZEISWP_FRAMECHANGED。

有两种方法将窗口设为最顶层窗口:一种是将参数hWndlnsertAfter设置为HWND_TOPMOST并确保没有设置SWP_NOZORDER标志;另一种是设置窗口在Z序中的位置以使其在其他存在的窗口之上。当一个窗口被置为最顶层窗口时,属于它的所有窗口均为最顶层窗口,而它的所有者的z序并不改变。

如果HWND_TOPMOST和HWND_NOTOPMOST标志均未指定,即应用程序要求窗口在激活的同时改变其在Z序中的位置时,在参数hWndinsertAfter中指定的值只有在下列条件中才使用:

在hWndlnsertAfter参数中没有设定HWND_NOTOPMOST和HWND_TOPMOST标志。

由hWnd参数标识的窗口不是激活窗口。

如果未将一个非激活窗口设定到z序的顶端,应用程序不能激活该窗口。应用程序可以无任何限制地改变被激活窗口在Z序中的位置,或激活一个窗口并将其移到最高级窗口的顶部或非最高级窗口的顶部。

如果一个顶层窗口被重定位到z序的底部(HWND_BOTTOM)或在任何非最高序的窗口之后,该窗口就不再是最顶层窗口。当一个最顶层窗口被置为非最顶级,则它的所有者窗口和所属者窗口均为非最顶层窗口。

一个非最顶端窗口可以拥有一个最顶端窗口,但反之则不可以。任何属于顶层窗口的窗口(例如一个对话框)本身就被置为顶层窗口,以确保所有被属窗口都在它们的所有者之上。

如果应用程序不在前台,但应该位于前台,就应调用SetForegroundWindow函数来设置。

Windows CE:如果这是一个可见的顶层窗口,并且未指定SWP_NOACTIVATE标志,则这个函数将激活窗口、如果这是当前的激活窗口,并且指定了SWP_NOACTIVATE或SWP_HIDEWINDOW标志,则激活另外一个可见的顶层窗口。

当在这个函数中的nFlags参数里指定了SWP_FRAMECHANGED标志时,WindowsCE重画窗口的整个非客户区,这可能会改变客户区的大小。这也是重新计算客户区的唯一途径,也是通过调用SetwindowLong函数改变窗口风格后通常使用的方法。

SetWindowPos将使WM_WINDOWPOSCHANGED消息向窗口发送,在这个消息中传递的标志与传递给函数的相同。这个函数不传递其他消息。

Windows CE 1.0不支持在hWndlnsertAber参数中的HWND_TOPMOST和HWND_NOTOPMOST常量。

Windows CE1.0不支持在fuFags参数中的SWP_DRAWFRAME和SWP_NOCOPYBITS标志。

Src:

import cv2
import numpy as np
import win32gui
import win32ui
import win32con
import win32apidef grab_screen(region=None):hwin = win32gui.GetDesktopWindow()if region:left, top, x2, y2 = regionwidth = x2 - left + 1height = y2 - top + 1else:width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)hwindc = win32gui.GetWindowDC(hwin)srcdc = win32ui.CreateDCFromHandle(hwindc)memdc = srcdc.CreateCompatibleDC()bmp = win32ui.CreateBitmap()bmp.CreateCompatibleBitmap(srcdc, width, height)memdc.SelectObject(bmp)memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)signedIntsArray = bmp.GetBitmapBits(True)img = np.fromstring(signedIntsArray, dtype='uint8')img.shape = (height, width, 4)srcdc.DeleteDC()memdc.DeleteDC()win32gui.ReleaseDC(hwin, hwindc)win32gui.DeleteObject(bmp.GetHandle())return cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)

0x03实现鼠标控制

为什么不用pyautogui

因为,通过代码测试,移动10次鼠标需要花费将近一秒时间,这个时间效率有点不够用

而pynput只用了几乎0秒

使用方法

首先将鼠标封装成一个类,这样mouse就成为了一个可操作的对象

mouse = pynput.mouse.Controller()

api-mouse.position鼠标位置

保存着鼠标当前的位置(mouse是mouse类实例)

from pynput.mouse import Controllerlock_mode = Falsemouse = Controller()while True:    x, y = mouse.position    print(x, y)

这段代码实时输出你的鼠标位置。注意哈,你的鼠标位置会受到屏幕缩放设置的影响,不是你是3840x2160,你的鼠标右下角位置就一定是3840x2160.

切换锁定模式---非阻塞版本

from pynput.mouse import Controller
lock_mode = False
def on_click(x, y, button, pressed):global lock_mode    #这里声明使用全局变量if pressed and button == button.x2: #x1,x2是鼠标侧面肩键lock_mode = not lock_mode   #模式切换# Collect events until released
with mouse.Listener(on_move=on_move,on_click=on_click,on_scroll=on_scroll) as listener:listener.join()# ...or, in a non-blocking fashion:
listener = mouse.Listener(on_move=on_move,on_click=on_click,on_scroll=on_scroll)
listener.start()

切换锁定模式---阻塞版本

import pynput
lock_mode = False
from pynput import mousewith mouse.Events() as events:while True:it = next(events)#当有操作且不是左键单击则读取下一个操作while it is not None and not isinstance(it, pynput.mouse.Events.Click):it = next(events)if it is not None and it.button == it.button.x2 and it.pressed:lock_mode = not lock_modeprint('lock mode','on' if lock_mode else 'off')

SRC:

import pynputdef lock(aims, mouse, x, y):#写规则,哪个离鼠标近先打哪个mouse_pos_x, mouse_pos_y = mouse.positiondist_list = []for det in aims:_, x_c, y_c, _, _ = detdist = (x * float(x_c) - mouse_pos_x) ** 2 + (y * float(y_c) - mouse_pos_y) ** 2dist_list.append(dist)det = aims[dist_list.index(min(dist_list))]tag, x_center, y_center, width, height = dettag = int(tag)#坐标转换x_center, width = x * float(x_center), x * float(width)y_center, height = y * float(y_center), y * float(height)#print(tag)if tag == 1:#如果锁头#print("111")mouse.position = (x_center, y_center)elif tag == 0:#如果锁身子#print("222")mouse.position = (x_center, y_center - 1 / 6 * height)import csv
import timedef recoil_control():f = csv.reader(open('./ammo_path/ak47.csv', encoding='utf-8'))ak_recoil = []for i in f:ak_recoil.append(i)ak_recoil[0][0] = '0'ak_recoil = [[float(i) for i in x] for x in ak_recoil]print(ak_recoil)k = -1.4mouse = pynput.mouse.Controller()flag = 0recoil_mode = False # mouse.button.x1with pynput.mouse.Events() as events:for event in events:if isinstance(event, pynput.mouse.Events.Click):if event.button == event.button.left:if event.pressed:flag = 1else:flag = 0if event.button == event.button.x1 and event.pressed:recoil_mode = not recoil_modeprint('recoil mode', 'on' if recoil_mode else 'off')if flag and recoil_mode:i = 0a = next(events)while True:mouse.move(ak_recoil[i][0] * k, ak_recoil[i][1] * k)i += 1if i == 30:breakif a is not None and isinstance(a, pynput.mouse.Events.Click) and a.button == a.button.left and not a.pressed:breaka = next(events)while a is not None and not isinstance(a, pynput.mouse.Events.Click):a = next(events)time.sleep(ak_recoil[i][2] / 1000)flag = 0

0x04 主逻辑

from grabscreen import grab_screen
from cs_model import load_model
import cv2
import win32gui
import win32con
import torch
import numpy as np
from utils.general import non_max_suppression, scale_coords, xyxy2xywh
from utils.augmentations import letterbox
import pynput
from mouse_control import lock, recoil_control
from threading import Thread
from pynput.mouse import Button, Controllerdevice = 'cuda' if torch.cuda.is_available() else 'cpu'
half = device != 'cpu'
imgsz = 640
conf_thres = 0.4
iou_thres = 0.05
x, y = (1280, 1024)  # 1280 * 1024
re_x, re_y = (2560, 1440)model = load_model()    #载入参数
stride = int(model.stride.max())
names = model.module.names if hasattr(model, 'module') else model.nameslock_mode = True        #是否开启索敌模式
mouse = Controller()   #鼠标对象初始化t = Thread(target=recoil_control)
t.start()with pynput.mouse.Events() as events:#print('~')while True:it = next(events)while it is not None and not isinstance(it, pynput.mouse.Events.Click):it = next(events)if it is not None and it.button == it.button.x2 and it.pressed:lock_mode = not lock_modeprint('lock mode', 'on' if lock_mode else 'off')img0 = grab_screen(region=(0, 0, x, y))img0 = cv2.resize(img0, (re_x, re_y))img = letterbox(img0, imgsz, stride=stride)[0]img = img.transpose((2, 0, 1))[::-1]img = np.ascontiguousarray(img)img = torch.from_numpy(img).to(device)  #对图片进行格式转换img = img.half() if half else img.float()img /= 255.if len(img.shape) == 3:img = img[None] # img = img.unsqueeze(0) 压缩数据维度pred = model(img, augment=False, visualize=False)[0]pred = non_max_suppression(pred, conf_thres, iou_thres, agnostic=False)#print(pred)aims = []   #定义一个列表for i, det in enumerate(pred):#det存放了四个位置数据,以比例形式呈现gn = torch.tensor(img0.shape)[[1, 0, 1, 0]]if len(det):#根据detect.py重构det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img0.shape).round()for *xyxy, conf, cls in reversed(det):# bbox:(tag, x_center, y_center, x_width, y_width)"""0 ct_head  1 ct_body  2 t_head  3 t_body"""xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywhline = (cls, *xywh)  # label formataim = ('%g ' * len(line)).rstrip() % lineaim = aim.split(' ')#print(aim)  #aim是列表格式aims.append(aim)    #添加到列表if len(aims):if lock_mode:lock(aims, mouse, x, y)#写鼠标锁人#画矩形框for i, det in enumerate(aims):#对于列表迭代_, x_center, y_center, width, height = detx_center, width = re_x * float(x_center), re_x * float(width)   #捕捉区域放缩y_center, height = re_y * float(y_center), re_y * float(height) #捕捉区域放缩top_left = (int(x_center - width / 2.), int(y_center - height / 2.))    #左上角位置计算bottom_right = (int(x_center + width / 2.), int(y_center + height / 2.))    #右下角位置计算color = (0, 255, 0) # RGB  用来画框的颜色cv2.rectangle(img0, top_left, bottom_right, color, thickness=3)     #画矩形框cv2.namedWindow('csgo-detect', cv2.WINDOW_NORMAL)cv2.resizeWindow('csgo-detect', re_x // 3, re_y // 3)cv2.imshow('csgo-detect', img0)hwnd = win32gui.FindWindow(None, 'csgo-detect')CVRECT = cv2.getWindowImageRect('csgo-detect')win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)   #一直置顶if cv2.waitKey(1) & 0xFF == ord('q'):cv2.destroyAllWindows()break

YOLOv5-CSGO深度学习图像识别自动瞄准技术用到的各个技术简述,着重分析使用的库和函数,如何实现鼠标调用,屏幕截取,制作训练集相关推荐

  1. 区域转换为二值图像_零基础一文读懂AI深度学习图像识别

    #寻找真知派# #科学思维看百态# #深度学习 图像识别# 人工智能大常识(2):图像识别(以手写字符识别为例) 近期写一组关于人工智能的科普帖子.第一帖介绍了AI自动诊断的方法,本帖之后准备继续推出 ...

  2. 检测、量化、追踪新冠病毒,基于深度学习的自动CT图像分析有多靠谱?

    作者 | Ophir Gozes, Maayan Frid-Adar等 译者 | 刘畅 出品 | AI科技大本营(ID:rgznai100) 背景:新冠病毒的传播非常迅速,并对数十亿人的生活产生了重大 ...

  3. 极市分享|第34期 袁源Jerry:机器学习及深度学习在自动驾驶中的应用

    | 极市线上分享 第34期 | ➤活动信息 主题:机器学习及深度学习在自动驾驶中的应用 时间:本周四(10月18日)晚20:00~21:30 ➤嘉宾信息 Jerry 贪心科技讲师,美国微软总部和美国亚 ...

  4. 地平线机器人_地平线机器人CEO余凯:基于深度学习的自动驾驶之路

    请关注公众号"汽车创新港",获取后续更多论坛实录! 加工作人员微信号:tinydanio,备注"我要入群"直接进入直播群! 今天都是大牛,下面的也是技术大牛,是 ...

  5. 基于深度学习的自动车牌识别(详细步骤+源码)

    点击下方卡片,关注" OpenCV与AI深度学习"公众号! 视觉/图像重磅干货,第一时间送达! 来源 | Learn OpenCV 作者 | Sanyam 翻译 | OpenCV与 ...

  6. GPU 选择 深度学习 图像识别

    GPU 选择 深度学习 图像识别 1.显卡 1.1.Nvidia显卡分类 1.1.1 Geforce系列 1.1.2 Quadro系列 1.1.3 Tesla系列 1.2 GPU几个比较重要的参数 G ...

  7. 深度学习-84:自动驾驶技术(L0-L5级别)

    深度学习-84:自动驾驶技术(L0-L5级别) 深度学习原理与实践(开源图书)-总目录, 建议收藏,告别碎片阅读! 人工智能在驾驶领域的应用最为深入.通过依靠人工智能.视觉计算.雷达.监控装置和全球定 ...

  8. 深度学习在自动驾驶领域的应用

    1.什么是深度学习 1.1  基本概念 深度学习即深度神经网络学习,其概念源于人工神经网络的研究,是一种特殊的机器学习形式:其目的在于建立和模拟人脑进行分析学习的神经网络,通过模仿人脑的接受和反馈机制 ...

  9. 麻省理工学院-2017年-深度学习与自动驾驶视频课程分享

    MIT最近放出了一套关于深度学习与自动驾驶应用的课程,主讲人Lex Fridman,MIT的一名博士后,主要半自动驾驶.场景感知.运动控制和规划等方向. 这门课程介绍了深度学习相关知识,以自动驾驶为载 ...

最新文章

  1. Flutter学习之Dart语法特性
  2. Android 使用Listview的优化
  3. 【317】python 指定浏览器打开网页 / 文件
  4. inmemory_通过Spring Boot了解H2 InMemory数据库
  5. 五合体机器人乐高_又来一波新品,高达、乐高全都有
  6. python tab键自动补全_设置python中TAB键自动补全方法
  7. vue 日期前面加0_NutUI - 京东开源的轻量级移动端Vue组件库
  8. indesign用于产品排班_2019年机器人行业十大新品盘点,过去一年最受关注的产品都在这...
  9. android模拟器设置静态ip,安卓模拟器多开挂手游改IP防封号技术讲解
  10. NodeMCU ESP8266+Arduino:将宿舍老式门锁改造为简易密码锁
  11. SLAM学习入门(1)针孔相机模型公式推导
  12. 转载:《星际争霸》韩国三大Zerg点评
  13. adobe清理工具_Adobe终于通过其新的渐变工具实现了这一点-UX评论
  14. CentOS部署单机Presto
  15. C#等语言、反射机制实现简单 智能语音人机交互(2)-- 皓月
  16. 汽车管理软件批发,汽车管理软件哪个靠谱?
  17. UDP通信多发多收(案例)和广播组播
  18. Shell 编程 ~ 从入门到入坑。
  19. FPGA 学习笔记:Vivado 生成的 Bitstream bit 文件 超大的解决方法
  20. vue自定义百度地图弹窗

热门文章

  1. UML建模工具2021年8-11月更新(2)UModel 2022
  2. 【六一儿童节】九九乘法表
  3. 怎样将计算机和电视机连接网络连接,网络电视机顶盒怎么连接电脑显示器
  4. WiFi6模组RW6852S-50
  5. python 百度云不限速版_GitHub - wdpython/pan-light: 百度网盘不限速客户端, golang + qt5, 跨平台图形界面...
  6. [GUET-CTF2019]虚假的压缩包
  7. HTML:网页设计案例2
  8. 自动贩卖机的c语言,自动售货机体统c++编程 问题描述】 自动售货机可以售出A、B、C三种商品,价格分别为1元、2元、知道...
  9. 【耗散结构论】耗散结构简介
  10. 【计算机系统】LC-3仿真器安装和使用