文章目录

  • 实验内容简介

  • 大致思路介绍

  • 结合代码实现算法

  • 总结与思考


一、实验内容简介

本文借鉴某学长思路,并添加上自己的理解,问题大致是,给定一段机械臂运动视频,通过边缘检测、直线检测,检测机械臂运动状况,并在图中标定出机械臂边缘与运动状态文字说明

二、大致思路介绍

将图片逐帧处理,对于每一帧图片,我们进行以下下操作:

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实现机械臂运动检测相关推荐

  1. python机械臂仿真_VTK与Python实现机械臂三维模型可视化详解

    三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...

  2. VTK与Python实现机械臂三维模型可视化详解

    三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...

  3. python机械臂仿真_使用VTK与Python实现机械臂三维模型可视化

    三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成 ...

  4. UR机械臂学习(8):Python实现机械臂运动控制(不使用MoveIt)

    以下是在gazebo仿真中使用,如果是控制真实机械臂,只需要修改订阅的话题即可 后期肯定会自己进行轨迹算法规划,用moveit的话想要更换算法太麻烦,所以尝试自己写程序不通过moveit来控制机械臂. ...

  5. Python 机器人学 —— 机械臂工作空间分析

    设关节1.关节5的高 (圆柱高) 分别为 ,5个关节的转动角分别为  可得出DH参数表: # 1 - 2 2 - 3 3 - 4 4 - * *- 5 5 - H 因为把各个关节的坐标系位置都定在了圆 ...

  6. python机械臂api_使用高斯机械臂的API开发

    对应不同的使用者,高斯机械臂提供以下几种开发方式: 使用Blockly开发 此种方式是使用 Studio 内置的编辑器来操作机械臂,适用于编程初学者,可以通过此种方式了解编程的基本概念,学习循环.条件 ...

  7. ROS moveit 机械臂笛卡尔空间运动

    机械臂moveit编程(python) 机械臂在笛卡尔空间的运动只能走点到点的直线运动,通过将位姿点加入waypoints中,机械臂会一次按照waypoints中的唯一依次沿直线运动到下一个点. 程序 ...

  8. python做运动控制_ROS探索总结-61.MoveIt!编程驾驭机械臂运动控制

    ROS探索总结-61.MoveIt!编程驾驭机械臂运动控制 说明: 介绍MoveIt!编程驾驭机械臂运动控制 正文 本讲我们将从以下四个部分进行讲解. 首先来回顾下MoveIt!编程接口的框架. Mo ...

  9. matlab机械臂工作空间代码_【ROS-Moveit!】机械臂控制探索(3)——基于python的API示例代码分析...

    本文参考Moveit!官方文档. 系统:ubuntu 18.04 / 16.04 ROS:Melodic / Kinetic 概述 基于python的运动组API是最简单的MoveIt!用户接口.其中 ...

最新文章

  1. mysql二进制日志文件差不多_mysql数据同步-基于二进制日志文件和position复制点的方式...
  2. 快速安装 Moodle 指南
  3. 设置UIImage的边框和圆角大小以及颜色
  4. 4核处理器_买电脑选4核、6核还是8核,从业是十年的专家终于讲清楚了差异
  5. IT职场人生系列之十七:入职(高手篇)
  6. oracle宣传片,会声会影X8震撼的宣传片效果该怎么制作?
  7. Python全栈之路——运算符(Day 02)
  8. vsan 一台主机磁盘组全报错_分享VSAN磁盘无法识别的故障解决方法
  9. 尚硅谷大数据开发Day03
  10. 我的团长我的团第三集
  11. Flutter 利用 FFI,绕过 Android JNI 直接调用 C++ 层!
  12. 树莓派系统安装 3.5寸LCD驱动安装 ssh远程链接
  13. 小程序蓝牙BLE——自动连接设备(手环)
  14. 选择计算机配件用户需求,买电脑都需要看什么?对电脑不太懂,配置什么的…...
  15. java数据库易错程序题_JAVA程序改错 (易错题)
  16. 网站快速成型工具-Element UI
  17. mac 下安装brew
  18. 免费开源的图片修复工具Lama Cleaner
  19. MySQL数据库增删改查SQL语句
  20. 为什么火狐浏览器打开默认是hao123

热门文章

  1. mysql 1067_mysql启动错误1067进程意外终止的解决方法
  2. Windows企业版2019安装,和显示无法打开所需文件d:\sources\install.wim.”解决办法
  3. 2016暑假集训小结
  4. Unity基础知识汇总
  5. 一个优秀IT专家的成长历程---献给所有的颓废或即将颓废的人们(ZZ)
  6. ACMCODER-股神
  7. 嵌入式系统基本概念(硬件篇)
  8. Splatter Painting
  9. ios系统邮件怎么绑定QQ邮箱
  10. Konga arm64 安装