PYTHON实现机械臂运动检测
文章目录
实验内容简介
大致思路介绍
结合代码实现算法
总结与思考
一、实验内容简介
本文借鉴某学长思路,并添加上自己的理解,问题大致是,给定一段机械臂运动视频,通过边缘检测、直线检测,检测机械臂运动状况,并在图中标定出机械臂边缘与运动状态文字说明
二、大致思路介绍
将图片逐帧处理,对于每一帧图片,我们进行以下下操作:
1、确定机械臂所在矩形域
2、利用高斯平滑化进行降噪处理
3、转化为灰度图并利用Canny边缘检测进行边缘图生成
4、将不感兴趣区域(除机械臂所在区域以外的区域)涂黑
5、进行直线检测判断是否运动
可以通过建立缓存区域进行该实现优化,后文会有具体算法与实现
三、结合代码实现算法
1、获取机械臂所在区域坐标
先获得第一帧图片,获取图片中两点坐标(两个点确定一个矩形区域)
2、利用高斯平滑进行降噪处理
代码如下
#高斯滤波
def clean_img(img):return cv.GaussianBlur(img,(5,5),0)
对于每一帧图片,为了使得边缘更加清晰,先对图片进行滤波处理,读者可以比较不同滤波方式的差异
3、图片添加文字
#图片添加文字, state=0:静止, state=1:运动
def addword(img,state):font = ImageFont.truetype("font/simsun.ttc", 32)img_pil = Image.fromarray(img)draw = ImageDraw.Draw(img_pil)if state == 0:draw.text((0, 0), "机械臂在静止", font = font, fill = (0, 2, 255))else:draw.text((0, 0), "机械臂在晃动", font=font, fill=(0, 2, 255))img = np.array(img_pil)return img
4、将不感兴趣区域涂黑
[x1, y1] = [288, 135]
[x2, y2] = [358, 166]#边缘图中只显示感兴趣的部分
def black(edges):global x1, y1, x2, y2wide, length = edges.shapeedges[0:wide, 0:x1] = 0edges[ 0:y1, 0:length] = 0edges[0:wide, x2:length] = 0edges[y2:wide, 0:length] = 0return edges
大致效果如下:
5、直线检测并绘制直线
#检测并绘制直线
def draw_line(img):img = clean_img(img)gray = cv.cvtColor(np.array(img), cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 60, 200)#转化为边缘图lines = cv.HoughLines(black(edges), 1, np.pi / 180, 20)global a, bfor line in lines:rho, theta = line[0]x1 = int(np.cos(theta) * rho - b * (-np.sin(theta)))y1 = int(np.sin(theta) * rho - b * (np.cos(theta)))x2 = int(np.cos(theta) * rho - a * (-np.sin(theta)))y2 = int(np.sin(theta) * rho - a * (np.cos(theta)))cv.line(img, (x1, y1), (x2, y2), (0, 0, 200), 3)#在图片上绘制直线k = (y2-y1)/(x2-x1)return img, k#输出第一条直线的斜率
可以通过调整Canny算子阈值,使得边缘检测灵敏度下降,使得直线检测效果更好
6、优化方案
逐帧处理会使得机械臂运动状态改变速度太快,为了使得降低改变速度,可以将逐帧处理改变为每次处理多帧信息,实现思路是建立一个缓存列表用于存储待处理的图片,伪代码如下:
1、
建立缓存数组list
2、
#IMG:需要处理的图片集合, img:其中一张图片, M:缓存数组容量
for img in IMG:
if len(list) < M:
将img添加到list
else:
处理list中相关信息
将list中图片输出
清空list
添加img到list中
while True:ret, frame = cap.read()if ret:if len(list) < M:list.append(frame)else:list.append(frame)sum_k = 0count = 0for i in list:img, k = draw_line(i)sum_k += klist[count] = imgcount += 1avr_k = sum_k/Mif abs(avr_k-k0) > ep:state = 1else:state = 0for i in list:img = addword(i, state)out.write(img)cv.namedWindow('jpg', cv.WINDOW_NORMAL)cv.imshow('jpg', img)list = []if cv.waitKey(1) & 0xFF == ord('q'):breakelse:break
7、完整代码
import cv2 as cv
import numpy as np
from PIL import ImageFont, ImageDraw, Image#均值滤波
def clean_img(img):return cv.GaussianBlur(img,(5,5),0)#边缘图中只显示感兴趣的部分
def black(edges):global x1, y1, x2, y2wide, length = edges.shapeedges[0:wide, 0:x1] = 0edges[ 0:y1, 0:length] = 0edges[0:wide, x2:length] = 0edges[y2:wide, 0:length] = 0return edges#图片添加文字, state=0:静止, state=1:运动
def addword(img,state):font = ImageFont.truetype("font/simsun.ttc", 32)img_pil = Image.fromarray(img)draw = ImageDraw.Draw(img_pil)if state == 0:draw.text((0, 0), "机械臂在静止", font = font, fill = (0, 2, 255))else:draw.text((0, 0), "机械臂在晃动", font=font, fill=(0, 2, 255))img = np.array(img_pil)return img#检测并绘制直线
def draw_line(img):img = clean_img(img)gray = cv.cvtColor(np.array(img), cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 60, 200)lines = cv.HoughLines(black(edges), 1, np.pi / 180, 20)global a, bfor line in lines:rho, theta = line[0]x1 = int(np.cos(theta) * rho - b * (-np.sin(theta)))y1 = int(np.sin(theta) * rho - b * (np.cos(theta)))x2 = int(np.cos(theta) * rho - a * (-np.sin(theta)))y2 = int(np.sin(theta) * rho - a * (np.cos(theta)))cv.line(img, (x1, y1), (x2, y2), (0, 0, 200), 3)k = (y2-y1)/(x2-x1)return img, kcap = cv.VideoCapture('D:/computer_view_exercise1/flapping_demo_video.avi')
[x1, y1] = [288, 135]
[x2, y2] = [358, 166]
b = 300
a = 375
k0 = (y2-y1)/(x2-x1)#初始斜率
ep = 0.05#判断是否运动的斜率阈值
count = 0#计数器
state = 0#运动标志变量fourcc = cv.VideoWriter_fourcc(*'XVID')
fps = cap.get(cv.CAP_PROP_FPS)
# 设置视频大小
size = (int(cap.get(cv.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)))
out = cv.VideoWriter('D:/computer_view_exercise1/out.avi',fourcc ,fps, size)
k = k0
list = []
M = 12#缓存最多图片张数while True:ret, frame = cap.read()if ret:if len(list) < M:list.append(frame)else:list.append(frame)sum_k = 0count = 0for i in list:img, k = draw_line(i)sum_k += klist[count] = imgcount += 1avr_k = sum_k/Mif abs(avr_k-k0) > ep:state = 1else:state = 0for i in list:img = addword(i, state)out.write(img)cv.namedWindow('jpg', cv.WINDOW_NORMAL)cv.imshow('jpg', img)list = []if cv.waitKey(1) & 0xFF == ord('q'):breakelse:breaksum_k = 0
count = 0
for i in list:img, k = draw_line(i)sum_k += klist[count] = imgcount += 1avr_k = sum_k/M
if abs(avr_k-k0) > ep:state = 1
else:state = 0
for i in list:img = addword(i, state)out.write(img)cv.namedWindow('jpg', cv.WINDOW_NORMAL)cv.imshow('jpg', img)
list = []cap.release()
out.release()
cv.destroyAllWindows()
总结
本实验遇到最大问题就是检测到的直线乱飞,进行思考发现原因是:转化为边缘图片后,发现除了要检测的目标(机械臂)外,还存在另外的边缘,因此我们采取滤波降噪处理,检测效果略好一些,但仍就不如意,我进行了将Canny算子替换成Sobel算子,企图降低边缘检测灵敏度,但Sobel算子也存在问题,会使得边缘不明显,因此我们通过改变Canny检测阈值,降低边缘检测灵敏度,取得不错效果
PYTHON实现机械臂运动检测相关推荐
- python机械臂仿真_VTK与Python实现机械臂三维模型可视化详解
三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...
- VTK与Python实现机械臂三维模型可视化详解
三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...
- python机械臂仿真_使用VTK与Python实现机械臂三维模型可视化
三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...
- UR机械臂学习(8):Python实现机械臂运动控制(不使用MoveIt)
以下是在gazebo仿真中使用,如果是控制真实机械臂,只需要修改订阅的话题即可 后期肯定会自己进行轨迹算法规划,用moveit的话想要更换算法太麻烦,所以尝试自己写程序不通过moveit来控制机械臂. ...
- Python 机器人学 —— 机械臂工作空间分析
设关节1.关节5的高 (圆柱高) 分别为 ,5个关节的转动角分别为 可得出DH参数表: # 1 - 2 2 - 3 3 - 4 4 - * *- 5 5 - H 因为把各个关节的坐标系位置都定在了圆 ...
- python机械臂api_使用高斯机械臂的API开发
对应不同的使用者,高斯机械臂提供以下几种开发方式: 使用Blockly开发 此种方式是使用 Studio 内置的编辑器来操作机械臂,适用于编程初学者,可以通过此种方式了解编程的基本概念,学习循环.条件 ...
- ROS moveit 机械臂笛卡尔空间运动
机械臂moveit编程(python) 机械臂在笛卡尔空间的运动只能走点到点的直线运动,通过将位姿点加入waypoints中,机械臂会一次按照waypoints中的唯一依次沿直线运动到下一个点. 程序 ...
- python做运动控制_ROS探索总结-61.MoveIt!编程驾驭机械臂运动控制
ROS探索总结-61.MoveIt!编程驾驭机械臂运动控制 说明: 介绍MoveIt!编程驾驭机械臂运动控制 正文 本讲我们将从以下四个部分进行讲解. 首先来回顾下MoveIt!编程接口的框架. Mo ...
- matlab机械臂工作空间代码_【ROS-Moveit!】机械臂控制探索(3)——基于python的API示例代码分析...
本文参考Moveit!官方文档. 系统:ubuntu 18.04 / 16.04 ROS:Melodic / Kinetic 概述 基于python的运动组API是最简单的MoveIt!用户接口.其中 ...
最新文章
- mysql二进制日志文件差不多_mysql数据同步-基于二进制日志文件和position复制点的方式...
- 快速安装 Moodle 指南
- 设置UIImage的边框和圆角大小以及颜色
- 4核处理器_买电脑选4核、6核还是8核,从业是十年的专家终于讲清楚了差异
- IT职场人生系列之十七:入职(高手篇)
- oracle宣传片,会声会影X8震撼的宣传片效果该怎么制作?
- Python全栈之路——运算符(Day 02)
- vsan 一台主机磁盘组全报错_分享VSAN磁盘无法识别的故障解决方法
- 尚硅谷大数据开发Day03
- 我的团长我的团第三集
- Flutter 利用 FFI,绕过 Android JNI 直接调用 C++ 层!
- 树莓派系统安装 3.5寸LCD驱动安装 ssh远程链接
- 小程序蓝牙BLE——自动连接设备(手环)
- 选择计算机配件用户需求,买电脑都需要看什么?对电脑不太懂,配置什么的…...
- java数据库易错程序题_JAVA程序改错 (易错题)
- 网站快速成型工具-Element UI
- mac 下安装brew
- 免费开源的图片修复工具Lama Cleaner
- MySQL数据库增删改查SQL语句
- 为什么火狐浏览器打开默认是hao123