牛!Python 也能实现图像姿态识别溺水行为了!
作者 | 李秋键
责编 | Carol
封图 | CSDN 下载自视觉中国
众所周知随着人工智能智能的发展,人工智能的落地项目也在变得越来越多,尤其是计算机视觉方面。
所以今天我们也是做一个计算机视觉方面的训练,用python来判断用户溺水行为,结合姿态识别和图像识别得到结果。其中包括姿态识别和图像分类。
首先图像分类是根据各自在图像信息中所反映的不同特征,把不同类别的目标区分开来的图像处理方法。它是利用计算机对图像进行定量分析,把图像或图像中的每个像元或区域划归为若干个类别中的某一种,以代替人的视觉判读。
人体姿态是被主要分为基于计算机视角的识别和基于运动捕获技术的识别。基于计算机视觉的识别主要通过各种特征信息来对人体姿态动作进行识别, 比如视频图像序列、人体轮廓、多视角等。
这里整体程序的流程如下:
百度姿态识别图片并标注
CNN网络实现图像分类
根据分类结果可视化输出结果
最终输出的程序效果如下图:
一、实验前的准备
首先我们使用的python版本是3.6.5所用到的模块如下:
OpenCV:用来调用姿态识别接口绘制姿态识别结果
Baidu-aip:用来加载人体分析模块实现人体姿态识别
configparser :配置文件模块 读写配置文件
keras:用来训练和调用神经网络模型
素材准备
首先我们准备不同的图片放到一个特定文件夹下。图片分为三个类别,一个是溺水图片文件夹,一个是正常游泳图片文件夹,另一个是疑似溺水无法判定的图片文件夹。在这里我们把它放到data文件夹下,
其中疑似图片文件夹,如下图可见:
人体姿态识别搭建
1、姿态配置文件设定:
在这里为了足够的精度和方便调用,我们使用百度提供的人体分析接口。按照官方的规定设定了配置文件。主要就是设定人体各个肢体零件连接配置。
其对应的代码如下:
def draw_line(self, img):# nose ---> neckcv2.line(img, (int(self.dic['nose']['x']), int(self.dic['nose']['y'])),(int(self.dic['neck']['x']), int(self.dic['neck']['y'])), (0, 255, 0), 2)# neck --> left_shouldercv2.line(img, (int(self.dic['neck']['x']), int(self.dic['neck']['y'])),(int(self.dic['left_shoulder']['x']), int(self.dic['left_shoulder']['y'])), (0, 255, 0), 2)# neck --> right_shouldercv2.line(img, (int(self.dic['neck']['x']), int(self.dic['neck']['y'])),(int(self.dic['right_shoulder']['x']), int(self.dic['right_shoulder']['y'])), (0, 255, 0), 2)# left_shoulder --> left_elbowcv2.line(img, (int(self.dic['left_shoulder']['x']), int(self.dic['left_shoulder']['y'])),(int(self.dic['left_elbow']['x']), int(self.dic['left_elbow']['y'])), (0, 255, 0), 2)# left_elbow --> left_wristcv2.line(img, (int(self.dic['left_elbow']['x']), int(self.dic['left_elbow']['y'])),(int(self.dic['left_wrist']['x']), int(self.dic['left_wrist']['y'])), (0, 255, 0), 2)# right_shoulder --> right_elbowcv2.line(img, (int(self.dic['right_shoulder']['x']), int(self.dic['right_shoulder']['y'])),(int(self.dic['right_elbow']['x']), int(self.dic['right_elbow']['y'])), (0, 255, 0), 2)# right_elbow --> right_wristcv2.line(img, (int(self.dic['right_elbow']['x']), int(self.dic['right_elbow']['y'])),(int(self.dic['right_wrist']['x']), int(self.dic['right_wrist']['y'])), (0, 255, 0), 2)# neck --> left_hipcv2.line(img, (int(self.dic['neck']['x']), int(self.dic['neck']['y'])),(int(self.dic['left_hip']['x']), int(self.dic['left_hip']['y'])), (0, 255, 0), 2)# neck --> right_hipcv2.line(img, (int(self.dic['neck']['x']), int(self.dic['neck']['y'])),(int(self.dic['right_hip']['x']), int(self.dic['right_hip']['y'])), (0, 255, 0), 2)# left_hip --> left_kneecv2.line(img, (int(self.dic['left_hip']['x']), int(self.dic['left_hip']['y'])),(int(self.dic['left_knee']['x']), int(self.dic['left_knee']['y'])), (0, 255, 0), 2)# right_hip --> right_kneecv2.line(img, (int(self.dic['right_hip']['x']), int(self.dic['right_hip']['y'])),(int(self.dic['right_knee']['x']), int(self.dic['right_knee']['y'])), (0, 255, 0), 2)# left_knee --> left_anklecv2.line(img, (int(self.dic['left_knee']['x']), int(self.dic['left_knee']['y'])),(int(self.dic['left_ankle']['x']), int(self.dic['left_ankle']['y'])), (0, 255, 0), 2)# right_knee --> right_anklecv2.line(img, (int(self.dic['right_knee']['x']), int(self.dic['right_knee']['y'])),(int(self.dic['right_ankle']['x']), int(self.dic['right_ankle']['y'])), (0, 255, 0), 2)
2、姿态识别调用:
在设置好基本的配置文件后,我们通过百度申请的账号密匙等等调用接口即可。这里实现的效果如下:
对应代码如下:
class BaiDuAPI(object):# 特殊 构造函数 初始化函数def __init__(self):app_id ="20038443"api_key = "LhtctcN7hf6VtkHHcUGwXKfw"secret_key = "wzWACH340kE0FGhvA9CqWsiRwltf5wFE"self.client = AipBodyAnalysis(app_id, api_key, secret_key)""" 读取图片 """def get_file_content(self, photoPath):with open(photoPath, 'rb') as fp:return fp.read()""" 主函数 """def file_main(self, photoPath):img = self.get_file_content('{}'.format(photoPath))""" 调用人体关键点识别 """# 此处只能对一个人进行关键点识别# 也就是说一个图片如果有好多人的话,只能标出一个人的关节特征# 此处可以做修改,即进行把一张图所有人的关节特征都表达出来# ------# print(self.client.bodyAnalysis(img))result = self.client.bodyAnalysis(img)['person_info'][0]['body_parts']jo = joint.Joint(result)jo.xunhun(photoPath)# print(result )
CNN识别模型的建立
1、神经网络的搭建:
这里设定的CNN模型挺常见的模型相似,通过设定卷积核、步长、训练批次等等搭建网络。
代码如下:
model = Sequential() #创建一个神经网络对象
#添加一个卷积层,传入固定宽高三通道的图片,以32种不同的卷积核构建32张特征图,
# 卷积核大小为3*3,构建特征图比例和原图相同,激活函数为relu函数。
model.add(Conv2D(input_shape=(IMG_W,IMG_H,3),filters=32,kernel_size=3,padding='same',activation='relu'))
#再次构建一个卷积层
model.add(Conv2D(filters=32,kernel_size=3,padding='same',activation='relu'))
#构建一个池化层,提取特征,池化层的池化窗口为2*2,步长为2。
model.add(MaxPool2D(pool_size=2,strides=2))
#继续构建卷积层和池化层,区别是卷积核数量为64。
model.add(Conv2D(filters=64,kernel_size=3,padding='same',activation='relu'))
model.add(Conv2D(filters=64,kernel_size=3,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=2,strides=2))
#继续构建卷积层和池化层,区别是卷积核数量为128。
model.add(Conv2D(filters=128,kernel_size=3,padding='same',activation='relu'))
model.add(Conv2D(filters=128,kernel_size=3,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=2, strides=2))
model.add(Flatten()) #数据扁平化
model.add(Dense(128,activation='relu')) #构建一个具有128个神经元的全连接层
model.add(Dense(64,activation='relu')) #构建一个具有64个神经元的全连接层
model.add(Dropout(DROPOUT_RATE)) #加入dropout,防止过拟合。
model.add(Dense(CLASS,activation='softmax')) #输出层,一共3个神经元,对应3个分类
adam = Adam(lr=LEARNING_RATE) #创建Adam优化器
model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy']) #使用交叉熵代价函数,adam优化器优化模型,并提取准确率
train_generator = train_datagen.flow_from_directory( #设置训练集迭代器TRAIN_PATH, #训练集存放路径target_size=(IMG_W,IMG_H), #训练集图片尺寸batch_size=BATCH_SIZE #训练集批次)
test_generator = test_datagen.flow_from_directory( #设置测试集迭代器TEST_PATH, #测试集存放路径target_size=(IMG_W,IMG_H), #测试集图片尺寸batch_size=BATCH_SIZE, #测试集批次)
print(train_generator.class_indices) #打印迭代器分类
try:model = load_model('{}.h5'.format(SAVE_PATH)) #尝试读取训练好的模型,再次训练print('model upload,start training!')
except:print('not find model,start training') #如果没有训练过的模型,则从头开始训练
model.fit_generator( #模型拟合train_generator, #训练集迭代器steps_per_epoch=len(train_generator), #每个周期需要迭代多少步epochs=EPOCHS, #迭代周期validation_data=test_generator, #测试集迭代器validation_steps=len(test_generator) #测试集迭代多少步)
model.save('{}.h5'.format(SAVE_PATH)) #保存模型
print('finish {} epochs!'.format(EPOCHS))
2、模型的调用:
同训练的步骤相似,这里我们首先也是是通过调用百度姿态识别进行图片人体分析,然后分类预测结果。
代码如下:
# 载入模型
model = load_model('model_selector.h5')
label = np.array(['正常','疑似','溺水'])
def image_change(image):image = image.resize((224, 224))image = img_to_array(image)image = image / 255image = np.expand_dims(image, 0)return image
class BaiDuAPI(object):# 特殊 构造函数 初始化函数def __init__(self):app_id ="20038443"api_key = "LhtctcN7hf6VtkHHcUGwXKfw"secret_key = "wzWACH340kE0FGhvA9CqWsiRwltf5wFE"self.client = AipBodyAnalysis(app_id, api_key, secret_key)""" 读取图片 """def get_file_content(self, photoPath):with open(photoPath, 'rb') as fp:return fp.read()""" 主函数 """def file_main(self, photoPath):img = self.get_file_content('{}'.format(photoPath))""" 调用人体关键点识别 """# 此处只能对一个人进行关键点识别# 也就是说一个图片如果有好多人的话,只能标出一个人的关节特征# 此处可以做修改,即进行把一张图所有人的关节特征都表达出来# ------# print(self.client.bodyAnalysis(img))result = self.client.bodyAnalysis(img)['person_info'][0]['body_parts']jo = joint.Joint(result)jo.xunhun(photoPath)# print(result )
#预测2.jpg的结果
try:image = load_img("2.jpg")#plt.imshow(image)image = image_change(image)baiduapi = BaiDuAPI()baiduapi.file_main('2.jpg')img=cv2.imread("temp.jpg")img_PIL = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))myfont = ImageFont.truetype(r'C:/Windows/Fonts/simfang.ttf', 40)draw = ImageDraw.Draw(img_PIL)draw.text((300, 10), label[model.predict_classes(image)][0], font=myfont, fill=(200, 100, 0))img_OpenCV = cv2.cvtColor(np.asarray(img_PIL), cv2.COLOR_RGB2BGR)cv2.imshow('frame', img_OpenCV)cv2.waitKey(0)
except:pass
#预测1.jpg的结果
try:image = load_img("1.jpg")#plt.imshow(image)image = image_change(image)baiduapi = BaiDuAPI()baiduapi.file_main('1.jpg')img=cv2.imread("temp.jpg")img_PIL = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))myfont = ImageFont.truetype(r'C:/Windows/Fonts/simfang.ttf', 40)draw = ImageDraw.Draw(img_PIL)draw.text((300, 10), label[model.predict_classes(image)][0], font=myfont, fill=(200, 100, 0))img_OpenCV = cv2.cvtColor(np.asarray(img_PIL), cv2.COLOR_RGB2BGR)cv2.imshow('frame', img_OpenCV)cv2.waitKey(0)
except:pass
#预测3.jpg的结果
try:image = load_img("3.jpg")#plt.imshow(image)image = image_change(image)baiduapi = BaiDuAPI()baiduapi.file_main('3.jpg')img=cv2.imread("temp.jpg")img_PIL = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))myfont = ImageFont.truetype(r'C:/Windows/Fonts/simfang.ttf', 40)draw = ImageDraw.Draw(img_PIL)draw.text((300, 10), label[model.predict_classes(image)][0], font=myfont, fill=(200, 100, 0))img_OpenCV = cv2.cvtColor(np.asarray(img_PIL), cv2.COLOR_RGB2BGR)cv2.imshow('frame', img_OpenCV)cv2.waitKey(0)
except:pass
最终运行程序结果如下:
源码地址:
https://pan.baidu.com/s/1qMwPCTTyqDWPXoPj1XnKgA
提取码:us2k
作者简介:
李秋键,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等等。
推荐阅读
高文、张钹、杨强隔空论道:AI精度与隐私的博弈
90行Python代码,让张小龙的微信地球转起来
独家揭秘!抖音爆款漫画变身特效的背后技术
字节跳动 8 年,抖音、头条的技术能力开发者都可以用起来了!
从微信「拍一拍」,我想到了那些神奇的一行代码功能
4 张图读懂比特币矿商8年兴衰与变迁
你点的每个“在看”,我都认真当成了AI
牛!Python 也能实现图像姿态识别溺水行为了!相关推荐
- python行为识别_牛!Python 也能实现图像姿态识别溺水行为了
作者 | 李秋键 责编 | Carol 封图 | CSDN 下载自视觉中国 众所周知随着人工智能智能的发展,人工智能的落地项目也在变得越来越多,尤其是计算机视觉方面. 所以今天我们也是做一个计算机视觉 ...
- Python,OpenCV骨架化图像并显示(skeletonize)
Python,OpenCV骨架化图像并显示(skeletonize) 1. 效果图 2. 源码 参考: 1. 效果图 自己画一张图,原图 VS 骨架效果图如下: opencv logo原图 VS 骨架 ...
- 使用Python,OpenCV制作图像Mask——截取ROIs及构建透明的叠加层
使用Python,OpenCV制作图像Mask--截取ROIs及构建透明的叠加层 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用OpenCV制作Mask图像掩码.使用位运算和图像掩码允许我们只 ...
- 使用Python,OpenCV实现图像和实时视频流中的人脸模糊和马赛克
使用Python,OpenCV实现图像和实时视频流中的人脸模糊和人脸马赛克 1. 效果图 2. 原理 2.1 什么是人脸模糊,如何将其用于人脸匿名化? 2.2 执行人脸模糊/匿名化的步骤 3. 源码 ...
- 使用Python和OpenCV检测图像中的条形码
使用Python和OpenCV检测图像中的条形码 1. 效果图 2. 算法的步骤 3. 源码 参考 这篇博客将介绍使用计算机视觉和图像处理技术进行条形码检测的必要步骤,并演示使用Python编程语言和 ...
- 使用Python,OpenCV查找图像中的最亮点
Python,OpenCV找出图像中的最亮点 1. 原理 2. 优化 3. 效果图 4. 源码 参考 这篇博客将向您展示如何使用Python和OpenCV查找图像中的最亮点,以及应用单行预处理代码-- ...
- 使用Python和OpenCV在图像之间执行超快速的颜色转换
使用Python和OpenCV在图像之间执行超快速的颜色转换 1. 效果图 2. 原理 2.1 颜色转移算法 2.2 步骤 2.3 算法改进 3. 源码 参考 这篇博客将介绍如何使用Python和Op ...
- 使用Python、OpenCV翻转图像(水平、垂直、水平垂直翻转)
使用Python.OpenCV翻转图像(水平.垂直.水平垂直翻转) 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python.OpenCV翻转图像,类似于cv2.rotate(). 沿y轴水 ...
- 使用Python,OpenCV计算图像直方图(cv2.calcHist)
使用Python,OpenCV计算图像直方图(cv2.calcHist 1. 效果图 2. 原理 2.1 什么是图像直方图? 2.2 计算直方图 2.3 可视化蒙版区域 3. 源码 参考 这篇博客将介 ...
最新文章
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'rtjhyt' in 'field list'
- SDN — 核心玩家与技术流派
- spring mvc DispatcherServlet详解之二---request通过Controller获取ModelAndView过程
- 深度之眼课程打卡-统计学习方法01
- 南京大学与东南大学计算机学院,南京被“严重低估”的1所大学,拥有8个A+学科,无奈校名太普通...
- python字典排序及字典集合去重高阶教程
- VB实现6大排序算法---动态过程展示(建议收藏)
- 查看文件时间及修改(MACN,stat命令,touch命令)
- OpenPose 升级,CMU提出首个单网络全人体姿态估计网络,速度大幅提高
- mysql 左右值算法详解_无限分类左右值算法的常规操作逻辑
- MS SQL入门基础:管理触发器
- 从零开始刷Leetcode——数组(941.977)
- Openwrt 路由器挂载摄像头教程
- 20145205 《信息安全系统设计基础》第1周学习总结
- Amobea读写分离
- git报错:fatal: 无法为 ‘https‘ 找到远程助手
- Android多线程理解
- 2D物理引擎--谁碰了我的奶酪
- EasyPoi word导出教程
- LeetCode知识点总结 - 2073
热门文章
- POJ 2778 AC自己主动机+矩阵幂 不错的题
- nginx 开发一个简单的 HTTP 模块
- 2014-3-6 星期四 [第一天执行分析]
- 关于并发处理,下列哪些说法符合《阿里巴巴Java开发手册》
- android jason动画,Android 动画之Lottie动画使用
- 《数据科学家养成手册》--“什么性质的人才能称得上科学家?” “科学的意思”
- Ubuntu安装QT后无法输入中文怎么办?
- leetcode网学习笔记(1)
- 洛谷 P2126 Mzc家中的男家丁
- 博客园第一天,开放封闭原则