使用Tensorflow+OpenCV构建会玩石头剪刀布的AI

磐创AI
关注

我已经使用DenseNet121模型进行特征提取,其输出最终将输入到我自己的Dense神经网络中。

densenet = DenseNet121(include_top=False, weights='imagenet', classes=3,input_shape=(300,300,3))

densenet.trainable=True

def genericModel(base):

model = Sequential()

model.add(base)

model.add(MaxPool2D())

model.add(Flatten())

model.add(Dense(3,activation='softmax'))

model.compile(optimizer=Adam(),loss='categorical_crossentropy',metrics=['acc'])

return model

dnet = genericModel(densenet)

history = dnet.fit(

x=imgData,

y=labels,

batch_size = 16,

epochs=8,

callbacks=[checkpoint,es],

validation_split=0.2

关键点 :由于我们的图片尺寸为300x300,因此指定的输入形状也为3x300x300,3代表RGB的维度信息,因此该层具有足够的神经元来处理整个图像。我们将DenseNet层用作第一层,然后使用我们自己的Dense神经网络。我已将可训练参数设置为True,这也会重新训练DenseNet的权重。尽管花了很多时间,但是这给了我更好的结果。我建议你在自己的实现中尝试通过更改此类参数(也称为超参数)来尝试不同的迭代。由于我们有3类Rock-Paper-Scissor,最后一层是具有3个神经元和softmax激活的全连接层。最后一层返回图像属于3类中特定类的概率。如果你引用的是GitHub repo(https://github.com/HOD101s/RockPaperScissor-AI-) 的train.py,则要注意数据准备和模型训练!至此,我们已经收集了数据,建立并训练了模型,剩下的部分是使用OpenCV进行部署OpenCV实现:此实现的流程很简单:启动网络摄像头并读取每个帧将此框架传递给模型进行分类,即预测类用电脑随意移动计算分数def prepImg(pth):

return cv2.resize(pth,(300,300)).reshape(1,300,300,3)

with open('model.json', 'r') as f:

loaded_model_json = f.read()

loaded_model = model_from_json(loaded_model_json)

loaded_model.load_weights("modelweights.h5")

print("Loaded model from disk")

for rounds in range(NUM_ROUNDS):

pred = ""

for i in range(90):

ret,frame = cap.read()

# Countdown

if i//20 < 3 :

frame = cv2.putText(frame,str(i//20+1),(320,100),cv2.FONT_HERSHEY_SIMPLEX,3,(250,250,0),2,cv2.LINE_AA)

# Prediction

elif i/20 < 3.5:

pred = arr_to_shape[np.argmax(loaded_model.predict(prepImg(frame[50:350,100:400])))]

# Get Bots Move

elif i/20 == 3.5:

bplay = random.choice(options)

print(pred,bplay)

# Update Score

elif i//20 == 4:

playerScore,botScore = updateScore(pred,bplay,playerScore,botScore)

break

cv2.rectangle(frame, (100, 150), (300, 350), (255, 255, 255), 2)
       frame = cv2.putText(frame,"Player : {}      Bot : {}".format(playerScore,botScore),(120,400),cv2.FONT_HERSHEY_SIMPLEX,1,(250,250,0),2,cv2.LINE_AA)

frame = cv2.putText(frame,pred,(150,140),cv2.FONT_HERSHEY_SIMPLEX,1,(250,250,0),2,cv2.LINE_AA)

frame = cv2.putText(frame,"Bot Played : {}".format(bplay),(300,140),cv2.FONT_HERSHEY_SIMPLEX,1,(250,250,0),2,cv2.LINE_AA)

cv2.imshow('Rock Paper Scissor',frame)

if cv2.waitKey(1) & 0xff == ord('q'):

break

上面的代码片段包含相当重要的代码块,其余部分只是使游戏易于使用,RPS规则和得分。所以我们开始加载我们训练过的模型,它在开始程序的预测部分之前显示倒计时,预测后,分数会根据球员的动作进行更新。

我们使用cv2.rectangle()显式地绘制目标区域,使用prepImg()函数预处理后,只有帧的这一部分传递给模型进行预测。

结论:我们已经成功地实现并学习了这个项目的工作原理,所以请继续使用我的实现进行其它实验学习。我做的一个主要的改进可能是增加了手部检测,所以我们不需要显式地绘制目标区域,模型将首先检测手部位置,然后进行预测。我鼓励你改进这个项目,并给我你的建议。精益求精!

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存