【Python】OpenCV从零开始的AI自瞄制作指南[上]

发布于 2023-08-28  823 次阅读


使用的软件:

  • Notepad+
  • OpenCV

使用的编程语言

  • Python

前言

OpenCV机器视觉训练图像识别AI开始,到利用AI模型识别目标,识别目标之后通过程序移动鼠标完成自瞄锁定。(因为最近在玩卡(卡拉彼丘)所以我这里就直接拿卡拉彼丘做示例,其他游戏只需要更换训练样本就重新训练就可以了)

本文章仅提供思路,如果有更好的方法,欢迎讨论

.注:本教程纯属学习用途,制作全过程将会在线下游戏进行,不可在线上游戏中使用!


1.获取训练样本

这里我用录制视频 + PR处理 + 取视频帧的方式来获得样本

样本需要正样本(pos)负样本(neg)

正样本即需要机器识别的图像,负样本即不需要机器识别需要排除的图像。

首先去靶场录个视频先~

放入PR,新建一个符合训练样本大小“序列”

然后创建运动的关键帧,最后再导出即可。

最后提取视频帧就可以了,这边粗略获得了574张样本。这里就不细选了,如果需要识别效果更好可以捕捉不同视角的样本

负样本重复以上方式就行。负样本最好是正样本的三倍,我这边粗略提取了2594张负样本

2.训练样本

创建三个文件夹来方便管理,把刚刚的样本放进去

这里还需要在cascade文件夹中创建一个关于正样本和负样本的描述文件

负样本的描述文件只需要在每一行写上负样本的路径即可(注意,前后都不能包含空格)

负样本有2594张,不可能手动书写,这边写一个bat文件来完成输入

@echo off
set /a i=0
:LoopStart
  echo E:\opencv341_bin-master\opencv341_bin-master\neg\%i%.JPG >> neg.txt
  set /a i+=1
  if %i% leq 2594 goto LoopStart #2594改成样本数量即可

正样本需要在每行写入样本路径 + 存在多少个目标 + 目标的X起始坐标 + 目标的Y起始坐标 + 目标的宽度 + 目标的高度

我这边是220 * 600的图片,我这边就写1 0 0 220 600

正样本稍微修改一下bat文件就可以了

@echo off
set /a i=0
:LoopStart
  echo E:\opencv341_bin-master\opencv341_bin-master\pos\%i%.JPG >> pos.txt
  set /a i+=1
  if %i% leq 574 goto LoopStart

打开cmd,运行opencv_createsamples.exe,将正样本转换成VEC文件

opencv_createsamples -info pos.txt -vec pos.vec -bg neg.txt -num 574 -w 24 -h 24
  • pos.txt 即刚才我们制作的正样本描述文件
  • neg.txt 即刚才制作的负样本描述文件
  • num 正样本数量
  • w、h 滑动窗口大小
  • pos.vec 即生成的vec文件

完成后会得到一个vec文件

在开始训练之前先在cascade文件夹中创建一个xml文件夹,用来存放生成好的xml文件

打开cmd,运行opencv_traincascade.exe,训练样本

opencv_traincascade -data xml -vec pos.vec -bg neg.txt -numPos 530 -numNeg 2594 -numStages 15 -featureType HAAR -w 24 -h 24 -mode ALL
  • pos.txt 即刚才我们制作的正样本描述文件
  • neg.txt 即刚才制作的负样本描述文件
  • numPos 正样本数量
  • numNeg 负样本数量
  • pos.vec vec文件
  • numStages 训练阶段数量
  • featureType 特征形式

注意,numPos正样本数量需要填写的比拥有的正样本数量少,最好小10%左右,不然在训练过程中或者开始的时候会报错

训练完成后就可以在xml文件夹中找到cascade.xml文件了,这是我们需要用到的。

3.训练结果测试

import cv2
    
#实例化分类器
player_cascade = cv2.CascadeClassifier('cascade.xml')
    
#读取测试图片
img = cv2.imread('4.jpg', cv2.IMREAD_COLOR)
#将原彩色图转换成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#开始在灰度图上检测,输出区域的外接矩形框
player = player_cascade.detectMultiScale(gray, 1.2, 8)
# 遍历检测结果
for (x, y, w, h) in player:
   #画框
   cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

       
# 显示画好矩形框的图片
cv2.namedWindow('Plater', 0)
cv2.imshow('Player', img)
# 等待退出键
cv2.waitKey(0)
# 销毁显示窗口
cv2.destroyAllWindows()

随便挑选一张截图,测试一下效果

uhmm...貌似是因为没有在负样本中添加UI界面的原因。重新在负样本中添加UI的负样本再次训练测试。

我这里是因为训练样本不够多导致的,可以继续增加负样本和正样本数量来确保最终质量。

我这边制作简单示范,我在python中添加了一个筛选绘制的框框大小的功能,当角色靠近目标,再绘制方框

import cv2
    
#实例化分类器
player_cascade = cv2.CascadeClassifier('cascade.xml')
    
#读取测试图片
img = cv2.imread('4.jpg', cv2.IMREAD_COLOR)
#将原彩色图转换成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#开始在灰度图上检测,输出区域的外接矩形框
player = player_cascade.detectMultiScale(gray, 1.2, 8)
x_ = 0
y_ = 0
w_ = 0
h_ = 0
area_ = 0
# 遍历检测结果
for (x, y, w, h) in player:
   #对比大小
   width = x + w - x
   hight = y + h - y
   area = width * hight
   if(area > area_):
      area_ = area
      x_ = x
      y_ = y
      w_ = w
      h_ = h
#画框
cv2.rectangle(img, (x_, y_), (x_ + w_, y_ + h_), (255, 0, 0), 2)
       
# 显示画好矩形框的图片
cv2.namedWindow('Plater', 0)
cv2.imshow('Player', img)
# 等待退出键
cv2.waitKey(0)
# 销毁显示窗口
cv2.destroyAllWindows()

4.最终效果