今年上报了一个大学生SRTP项目,准备用树莓派作为主控板实现一个智能捡网球机。由于opencv开发库提供了大量图像处理算法的接口,因此只要一定程度上熟悉python语法和opencv库,实现这个程序并不是特别麻烦。本文会主要写程序实现的过程,不会涉及到很多的理论性的知识,有兴趣深入了解的可以自行查找网络上的各种资料。


本项目以网球的颜色作为识别特征。

识别过程为:获取视频帧----转换到HSV颜色空间----规定阈值、切割图像----识别轮廓获得网球位置信息

获取视频帧:

在树莓派上搭载摄像头获取视频帧不用多提,连接上摄像头然后直接opencv调用即可。因为在树莓派上安装opencv可以能涉及到到需要重新编译等各种问题,想避免麻烦的同学可以尝试直接pip opencv-python。树莓派摄像头可以选择官方的CSI摄像头,我为了便于在电脑上进行分析和调试,选用了usb线传输的摄像头模块,这种模块某宝上很多,使用起来也很简单。

转换颜色空间:

在HSV颜色空间下进行颜色识别能够很好地降低调试难度,提高识别精度。就作者本人的理解,RGB空间下的三通道是互相独立互不关联的,而HSV空间下的三通道值之间具有一定的关系或者说是主次区别,更容易分级调试确定阈值和修正因环境光影响产生的阈值偏移问题,同时HSV空间更符合人的视觉习惯。

转换颜色空间可用opencv的cvtColor函数实现。

hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

注意!!!经过cvtColor函数转换后的图像HSV三通道的取值范围与普遍认知下的HSV通道取值范围不同,可能是为了统一数据类型,opencv将原范围(h:0~360°, s:0~1, v:0~1)映射到了(h:0~180, s:0~255, v:0~255)的空间上。

规定阈值、切割图像:

在颜色空间转换完成后,下一步需要确定网球颜色范围。首先用我们的摄像头拍摄一张照片,从中截取出网球部分进行颜色分析,可以调用calcHist函数和matplotlab包快速实现。

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) ->hist

calcHist()是用于计算颜色直方图的函数,参数意义分别是:

images:输入图像。

channels:图像通道。

mask:掩膜,不使用时置None。

histSize:产生的直方图尺寸,一般与通道值范围有关。

ranges:像素值的范围。

calcHist()会返回hist格式数据,可以直接使用plot()函数进行可视化处理。代码如下:

from matplotlib import pyplot as pltimg = cv2.imread('/test.jpg')
hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
hist_H = cv2.calcHist([hsv_img],[0],None,[181],[0,180])
hist_S = cv2.calcHist([hsv_img],[1],None,[256],[0,255])
hist_V = cv2.calcHist([hsv_img],[2],None,[256],[0,255])    #获得不同通道的颜色直方图
plt.plot(hist_V),plt.xticks(np.arange(0,255,10))           #画图
plt.show()

对截取出的网球图像进行颜色分析得出三通道图:

H通道值

V通道值

S通道值

从图中我们可以直接观察出网球颜色的大致分布区间,先用得到大致分布区间进行图像的预切割。

图像切割函数为:

cv2.inRange(src, lowerb, upperb[, dst]) → dst

参数意义为:

src:输入图像

lowerb:阈值下限

upperb:阈值上限

返回跟原图大小相同的图像矩阵,满足阈值的位置将被置255,其他位置置0。

对图像进行预切割的效果如下(原图来自网络):

原图

预切割效果

从预切割效果图中可以看出,我们直接观察得到的阈值可以把一部分网球提取出来,但由于网球与摄像头距离、角度的不同,初始阈值并不完全适用与所有网球,因此还需要进一步的调整。作者采用的方法是通过滑动条来实现阈值的动态调整。

cv2.namedWindow('value')
cv2.createTrackbar('h','value',0,180,nothing)
cv2.createTrackbar('_h','value',0,50,nothing)
cv2.createTrackbar('s','value',0,255,nothing)
cv2.createTrackbar('_s','value',0,100,nothing)
cv2.createTrackbar('v','value',0,255,nothing)
cv2.createTrackbar('_v','value',0,100,nothing)while 1:k = cv2.waitKey(10)if k == ord('m'):cv2.destroyAllWindows()breakelif k == ord('n'):print(cv2.getTrackbarPos('h', 'value'), cv2.getTrackbarPos('s', 'value'), cv2.getTrackbarPos('v', 'value'))lower_green = np.array([15,180,150])lower_green = np.array([cv2.getTrackbarPos('h', 'value')-cv2.getTrackbarPos('_h','value'), \cv2.getTrackbarPos('s', 'value')-cv2.getTrackbarPos('_s','value'), \cv2.getTrackbarPos('v', 'value')-cv2.getTrackbarPos('_v','value')])higher_green = np.array([30,255,255])higher_green = np.array([cv2.getTrackbarPos('h', 'value') + cv2.getTrackbarPos('_h', 'value'), \cv2.getTrackbarPos('s', 'value') + cv2.getTrackbarPos('_s', 'value'), \cv2.getTrackbarPos('v', 'value') + cv2.getTrackbarPos('_v', 'value')])mask = cv2.inRange(hsv_img, lower_green, higher_green) cv2.imshow("balls", mask)

通过滑动条调整阈值大小,直到程序能够识别出大部分网球且不会出现大量误判为止,大体效果如下:

合适阈值的效果图

记录当前阈值,用于识别程序。

识别轮廓获得图像位置:

经过切割图像后我们获得了含有网球位置信息的黑白掩膜图像,读取出网球的位置信息我们就初步实现了识别程序。黑白掩膜图像是单通道灰度图象,且边缘处像素值突变明显,用轮廓识别函数就可以很简单的获得相关位置信息。轮廓识别函数为:

cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])  

参数意义:

image:输入图像

mode:轮廓识别模式。为了避免网球内部噪点的影响,这里可使用cv2.RETR_EXTERNAL只检测外轮廓。

method:输出的轮廓数据类型。这里我们单纯需要简单位置信息,可以使用cv2.CHAIN_APPROX_SIMPLE获得四点坐标。

findContours()会返回一个轮廓列表,然后利用列表中数据在图中画出识别框。

contours, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:x,y,w,h = cv2.boundingRect(c)cv2.rectangle(img, (x-d,y-d), (x+w+d,y+h+d),(0,0,255),2)

识别结果如下:

识别效果

目前,我们就大体上完成了网球识别程序,在实际应用过程中光照影响还是比较严重的,使用时可能需要调整阈值范围。可以尝试监听鼠标点击获得当前网球颜色值调整范围等办法,在此就不一一详述了。

基于python+opencv的网球识别相关推荐

  1. 【开源分享】基于Python+OpenCV+PyQt5车牌识别(GUI界面)

    亲测无错:基于Python+OpenCV+PyQt5车牌识别(GUI界面)绝对可以用的!!!!! 基于Python+OpenCV+PyQt5车牌识别(GUI界面) 参考文档

  2. 基于Python+OpenCV的人脸识别实现带墨镜效果

    环境以及执行步骤 相关介绍 环境配置 相关库安装介绍 上代码 github地址 动图介绍 改进 相关介绍 你好! 项目起初来源于一本科生的毕业设计,由于我给了一版更加优秀,所以初始版本的例子给予分享. ...

  3. 基于Python opencv实现车牌识别及二维码条形码识别系统 附完整源码

    完整代码:https://download.csdn.net/download/qq_38735017/87416699 原理简介 车牌字符识别使用的算法是 opencv 的 SVM opencv 的 ...

  4. python读取视频流做人脸识别_基于 Python + OpenCV 进行人脸识别,视频追踪代码全注释...

    1 #-*- coding: utf-8 -*- 2 from __future__ importunicode_literals3 #操作文件 4 importos5 #科学计算 6 importn ...

  5. 基于python+Opencv的车牌识别

    车牌识别包括车牌检测(通过图像分割.特征提取获得车牌位置)+车牌识别(对检测到的车牌进行字符内容识别). 一.基本流程如下: 1.车牌检测 1)读取需要进行车牌识别的图片: 2)对图像进行灰度化处理( ...

  6. 基于python+OpenCV的车牌号码识别

    基于python+OpenCV的车牌号码识别 车牌识别行业已具备一定的市场规模,在电子警察.公路卡口.停车场.商业管理.汽修服务等领域已取得了部分应用.一个典型的车辆牌照识别系统一般包括以下4个部分: ...

  7. 基于python opencv人脸识别的签到系统

    基于python opencv人脸识别的签到系统 前言 先看下效果 实现的功能 开始准备 页面的构建 功能实现 代码部分 总结 前言 一个基于opencv人脸识别和TensorFlow进行模型训练的人 ...

  8. Python人脸识别教程 - 基于Python的开源人脸识别库:离线识别率高达99.38%

    Python人脸识别教程 - 基于Python的开源人脸识别库:离线识别率高达99.38% 仅用 Python 和命令行就可以实现人脸识别的库开源了.该库使用 dlib 顶尖的深度学习人脸识别技术构建 ...

  9. Python+Opencv简易车牌识别(二):形态学运算,HSV颜色空间筛选与图像分割

    注:这是依然一个简单的车牌识别demo 1.前言 在上一篇Python+Opencv简易车牌识别(一):基于HSV颜色空间的图像分割中,我们讲了如何仅基于颜色来进行简单粗暴的车牌分割.今天我们考虑对图 ...

最新文章

  1. php网站怎么伪静态,php怎么实现网页伪静态
  2. git设置单个仓库用户名以及密码
  3. 独家 | 一文了解强化学习的商业应用
  4. resultType 与resultMap 的区别
  5. 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
  6. ajax请求_重复的ajax请求让人很受伤
  7. 使用heroku进行免费分布式运算.Vs.AWS
  8. Qt-IP地址查询工具(使用HTTP GET方法)
  9. pythoncanny边缘检测自适应阈值_一种自适应阈值的Canny边缘检测算法
  10. 一文讲懂蓝绿发布和金丝雀发布
  11. 热备份冗余技术HSRP
  12. Pixelmator Pro for Mac(图像编辑软件)
  13. The package java.awt is not accessible的解决方案
  14. KittenCode编程平台
  15. IE浏览器控制台空白
  16. VSCode下载及各种实用插件安装教程
  17. html播放rtsp低延时(局域网测试500ms左右)
  18. 减去“商品名”这层包装外衣,让你看清“药品名”的真谛 - 看看你的感冒在中西医各怎样解读与配药
  19. 关于二极管与三极管的理解——模拟电路基础
  20. elasticsearch 如何保证数据一致性?

热门文章

  1. 计算机网络培训班能学着东西吗,计算机网络培训心得
  2. CKFinder 介绍
  3. 万向区块链董事长肖风莅临成都链安 对成都链安在区块链安全方面的贡献高度赞扬...
  4. 【蓝桥杯算法题】用java遍写税收计算
  5. 大学毕业论文字数有上限吗,我写了一万六千字,指导老师让我删掉一万字关键第二天就要交,怎么办?...
  6. 数字图像处理作业: 包含质量因子的 JPEG压缩 python代码
  7. 自动驾驶少了“技术偷窃”,还能玩得转吗?
  8. Matlab编程:实现傅里叶变换
  9. 移动智能网期末考知识点整理
  10. 揭开百度工程师的神秘面纱:用数字说话