pid摄像头循迹(opencv和openmv)

2023-05-16

pid摄像头循迹(opencv和openmv)

  • 用摄像头进行循迹的方法参考
    • 硬件选型方面
    • 软件思路
    • 一.图像预处理:
    • 代码部分
    • 二.线性拟合
    • opencv线性拟合:
    • 实际在树莓派上运行时,帧率也比较高,拟合效果也比较好。
    • 三.PID控制
    • 关于控制直流电机:

用摄像头进行循迹的方法参考

去年用openmv做了一个循迹小车,效果还不错,实验室里做了汇报,这里也同步分享一下制作的一些细节。
小车灰常简陋,当时硬件水平有限,轻喷>_<
在这里插入图片描述
csdn视频放不出来,只能放已经投稿的视频,这里就不展示了叭。
运行效果其实和openmv官方教程给的视频里小车效果类似,大家可以作为参考。

硬件选型方面

  1. 稳压模块x2
  2. 9v锂电池x1
  3. openmv
  4. 减速电机(6v 280rpm)
  5. 万向轮
  6. L298N直流电机驱动模块
    (插一下,这里的稳压可以稳压到7V和3.3V,L298N本身可以将电压稳压到5V)

软件思路

在这里插入图片描述
如上图所示,分为图像预处理、线性拟合以及PID控制转速。

一.图像预处理:

1.按阈值取二值化 (可以加入中值滤波或高斯滤波)
2.腐蚀操作 (去除噪点)
3.膨胀操作(可有可无)
因为openmv的算力有限,若是同时加上了膨胀和腐蚀操作,运行循迹程序时帧率会变得很低(可能低于15fps)。

代码部分

图像预处理在openmv和opencv中均有现成的库函数,直接调用即可。
1.openmv

img.dilate(2) #膨胀
img.erode(2)# 腐蚀
img = sensor.snapshot().binary([THRESHOLD]) # 按阈值二值化

2.opencv

mask=cv2.inRange(img,black_min,black_max) #二值化
kernel=np.ones((3,3),np.uint8) #半径大小
erode=cv2.morphologyEx(mask,cv2.MORPH_ERODE,kernel)# 腐蚀

腐蚀膨胀 示意图如下所示:
在这里插入图片描述

二.线性拟合

这里的线性拟合采用的是最小二乘法进行拟合,遍历所有像素点,复杂度为O(n²)
openmv有现成的库函数:

line = img.get_regression([(100,100,0,0,0,0)], robust = True)

官网给的解释是快速鲁棒线性回归
可以直接返回得到拟合的直线对象

参考文档:https://docs.singtown.com/micropython/zh/latest/openmvcam/library/omv.image.html?highlight=get_regression#image.get_regression

官方文档介绍:
在这里插入图片描述

opencv线性拟合:

由于我没有找到相关的线性拟合函数,于是自己写了一个函数:
传入参数img为二值化图像,result为原图。

# 线性拟合
def liner(img,result):
    # print(img)
    n=[len(img[:,0]),len(img[0,:])]
    # print(n,'n')
    (x_point,y_point)=np.nonzero(img)
    if len(x_point)<2:
        return 0
    f1 = np.polyfit(x_point, y_point,1)
    p1 = np.poly1d(f1)
    point1=(int(p1(0)),0)
    point2=(int(p1(n[0])),n[0])
    print(point2,point1)
    result = cv2.line(result, (int(n[1]/2),0) , (int(n[1]/2),n[0]), (0, 0, 255),2)
    result=cv2.line(result,point1,point2,(0,255,0),2)
    cv2.imshow('inside',result)
    print(f1)
    return [n[1]/2-p1(n[0]),f1[1]]

返回值为拟合的直线与图像下方中点的距离和函数的k值
运行效果如下:

在这里插入图片描述
从左到右分别为:
1.腐蚀后的图像 2.拟合效果图像 3.二值化图像

实际在树莓派上运行时,帧率也比较高,拟合效果也比较好。

在这里插入图片描述
可以看到有81帧每秒,运行速度较为不错。

三.PID控制

在这里插入图片描述
pid算法对于熟悉控制算法来说已经是非常常见的算法了,这里就不过多介绍,直接贴代码:
(这里pid的调整输入为角度theta和距离rho)

import time
from math import pi, isnan

# 定义pid
class PID:
    _kp = _ki = _kd = _integrator = _imax = 0
    _last_error = _last_derivative = _last_t = 0
    _RC = 1/(2 * pi * 20) # 车身参数
    def __init__(self, p=0, i=0, d=0, imax=0):
        self._kp = float(p) # 比例
        self._ki = float(i) # 积分
        self._kd = float(d) # 微分
        self._imax = abs(imax)
        self._last_derivative = float('nan')

    def get_pid(self, error, scaler):
        tnow = time.time()*1000 # 当前时间,单位为ms
        dt = tnow - self._last_t
        output = 0
        if self._last_t == 0 or dt > 1000:
            dt = 0
            self.reset_I() # 防止积分系数过大
        self._last_t = tnow
        delta_time = float(dt) / float(1000)
        output += error * self._kp
        if abs(self._kd) > 0 and dt > 0:
            if isnan(self._last_derivative):
                derivative = 0
                self._last_derivative = 0
            else:
                derivative = (error - self._last_error) / delta_time
            derivative = self._last_derivative + \
                                     ((delta_time / (self._RC + delta_time)) * \
                                        (derivative - self._last_derivative))
            self._last_error = error
            self._last_derivative = derivative
            output += self._kd * derivative
        output *= scaler
        if abs(self._ki) > 0 and dt > 0:
            self._integrator += (error * self._ki) * scaler * delta_time
            if self._integrator < -self._imax: self._integrator = -self._imax
            elif self._integrator > self._imax: self._integrator = self._imax
            output += self._integrator
        return output
    def reset_I(self):
        self._integrator = 0
        self._last_derivative = float('nan')

一些问题:

newimg=155*np.ones(shape,dtype = np.uint8)

在转化时注意类型转化

img=cv2.resize(img,(480,640))

cv2.inRange %用于按阈值取二值化的函数:

关于控制直流电机:

openmv中控制电机可以采用定时器输出pwm来控制电机
而在树莓派中可以调用RPi.GPIO库或pigpio库来实现。
以RPi.GPIO库为例:

p = GPIO.PWM(channel, frequency)
p.start(dc)   # dc 代表占空比(范围:0.0 <= dc <= 100.0)
p.ChangeFrequency(freq)   # freq 为设置的新频率,单位为 Hz
p.ChangeDutyCycle(dc)  # 范围:0.0 <= dc <= 100.0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pid摄像头循迹(opencv和openmv) 的相关文章

  • opencv 视频上的颜色阈值

    I am thresholding for a color range in an opencv video The goal is to seperate the B mode black and white information on
  • 使用相位相关和对数极坐标变换获得旋转位移

    我一直在编写一个脚本 它使用 cv2 计算两个图像之间的旋转位移phaseCorrelate method 我有两张图像 第二张是第一张图像的 90 度旋转版本 加载图像后 我将它们转换为对数极坐标 然后将它们传递到phaseCorrela
  • 在 Python 3.5 64 位上通过 pip 安装 OpenCV

    我尝试安装 OpenCV 但找不到任何合适的 pip 软件包 我决定上网查找有关如何安装它的官方文档 并发现this https opencv python tutroals readthedocs io en latest py tuto
  • brew 链接 jpeg 问题

    我正在尝试安装opencv在 Mac OSX Lion 上 brew install opencv 我收到以下错误 以及其他一些类似的错误 Error The linking step did not complete successful
  • 查找彼此接近的对象边界

    我正在研究一个计算机视觉问题 其中问题的第一步是找到物体彼此靠近的位置 例如 在下图中 我感兴趣的是找到灰色标记的区域 Input Output 我目前的方法是首先反转图像 然后通过侵蚀进行形态梯度跟随 然后删除一些不感兴趣的轮廓 脚本如下
  • 计算两个描述符之间的距离

    我正在尝试计算已计算的两个描述符之间的距离 欧几里得或汉明 问题是我不想使用匹配器 我只想计算两个描述符之间的距离 我正在使用 OpenCV 2 4 9 并且我的描述符存储在 Mat 类型中 Mat descriptors1 Mat des
  • Opencv未找到所有轮廓

    我试图找到该图像的轮廓 但是该方法查找轮廓只返回1轮廓 轮廓突出显示image 2 我正在努力寻找all外部轮廓就像这些圆圈 里面有数字 我究竟做错了什么 我可以做什么来实现它 image 1 image 2 以下是我的代码的相关部分 th
  • 提高 pytesseract 从图像中正确识别文本的能力

    我正在尝试使用读取验证码pytesseract模块 大多数时候它都能提供准确的文本 但并非总是如此 这是读取图像 操作图像以及从图像中提取文本的代码 import cv2 import numpy as np import pytesser
  • OpenCV的拼接模块可以拼接平行运动相机拍摄的图像吗?

    我想知道是否缝合 http docs opencv org modules stitching doc stitching html http docs opencv org modules stitching doc stitching
  • 在加载“cv2”二进制扩展期间检测到递归

    我有一个小程序 在 pyinstaller 编译后返回 opencv 错误 但无需编译即可工作 我在 Windows 10 上使用 Python 3 8 10 Program 导入 pyautogui将 numpy 导入为 np导入CV2
  • 如何将 mat 转换为 array2d

    我为dlib http dlib net face landmark detection ex cpp html那里的面部地标代码使用 array2d 来获取图像 但我喜欢使用 Mat 读取图像并转换为 array2d 因为 dlib 仅支
  • OpenCV 仅围绕大轮廓绘制矩形?

    第一次发帖 希望我以正确的方式放置代码 我正在尝试检测和计算视频中的车辆 因此 如果您查看下面的代码 我会在阈值处理和膨胀后找到图像的轮廓 然后我使用 drawContours 和矩形在检测到的轮廓周围绘制一个框 我试图在 drawCont
  • 多视图几何

    我从相距一定距离的两台相同品牌的相机捕获了两张图像 捕获了相同的场景 我想计算两个相机之间的现实世界旋转和平移 为了实现这一点 我首先提取了两张图像的 SIFT 特征并进行匹配 我现在有基本矩阵也单应性矩阵 然而无法进一步进行 有很多混乱
  • opencv形态扩张滤波器作为最大滤波器

    就像中值滤波器的定义一样 我可以将 最大滤波器 定义为局部窗口 例如dst x y max 3x3 局部窗口像素 但我在opencv中找不到这样的过滤器 最接近的是 dilate 函数 然后我使用 dilate 函数的默认配置 但结果不正确
  • 如何在bash中列出所有后台pid

    要么我无法正确表达我的搜索 要么答案不容易找到 但我正在尝试找出如何列出我的所有后台任务 PID 例如 到目前为止 我发现要列出我们使用的最后一个 PID 但现在我想列出之前任务的 PID 如果存在 但我找不到如何做到这一点 最终我想列出我
  • OpenCV C++ 如何知道每行的轮廓数进行排序?

    我有一个二值图像 https i stack imgur com NRLVv jpg在这张图片中 我可以使用重载的函数轻松地对从上到下 从左到右找到的轮廓进行排序std sort 我首先通过以下方式从上到下排序 sort contours
  • 创建 OpenCV 的 mouseCallback 函数的基于类的实现时遇到问题

    正如标题所示 我在基于类的 C 结构中实现 OpenCV 的 mouseCallback 函数时遇到了一些麻烦 请允许我解释一下 我定义了一个名为 BriskMatching 的类 在其中创建了一个名为 mouseCallback 的成员函
  • ffmpeg AVFrame 到 opencv Mat 转换

    我目前正在开发一个使用 ffmpeg 解码接收到的帧的项目 解码后 我想将 AVFrame 转换为 opencv Mat 帧 以便我可以在 imShow 函数上播放它 我拥有的是字节流 我将其读入缓冲区 解码为 AVFrame f fope
  • OpenCV 错误:connectedComponents_sub1 中断言失败 (L.channels() == 1 && I.channels() == 1) [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我在 OpenCV python 中遇到以下错误 并用 google 搜索了很多 但无法解决 如果有人能为我提供一些线索
  • 如何将 Mat (opencv) 转换为 INDArray (DL4J)?

    我希望任何人都可以帮助我解决这个任务 我正在处理一些图像分类并尝试将 OpenCv 3 2 0 和 DL4J 结合起来 我知道DL4J也包含Opencv 但我认为它没什么用 谁能帮我 如何转换成 INDArray 我尝试阅读一些问题here

随机推荐

  • 在CSDN发布博客怎么改变代码块颜色

    第一步 CSDN首页 xff0c 最右侧点击创作中心 第二步 左侧导航栏滑到最下面 xff0c 点击博客设置 第三步 找到代码片样式 xff0c 简单吧 xff08 又水了一篇 xff09
  • 裸机驱动与Linux设备驱动的区别

    裸机驱动一般针对没有操作系统支持的层面 不用考虑操作系统对它的调用 Linux驱动是在裸机驱动基础上 按照一定的规范来实现 虽然实现的都是同一个东西 不过你发现在 Linux驱动 搀杂 了许多维护信息 总之 xff0c Linux设备驱动就
  • 使用2020版IDEA创建Servlet

    使用2020版IDEA创建一个完整的Web项目的整个过程分为四步 第一步 创建一个普通的Java项目 1 打开IDEA xff0c 选择菜单File gt New gt Project 2 选择Java xff0c 以及自己的JDK xff
  • Apache IoTDB 系列教程-5:常见问题汇总(1)

    在过去的一段时间 xff0c 收集了不少大家在使用过程中反馈的问题 xff0c 今天把一些常见问题列出来 xff0c 给更多人提供参考 开了个交流群二维码 xff0c 可以扫码进群 正文 1974 字 xff0c 预计阅读时间 5 分钟 常
  • Apache IoTDB 系列教程-6:性能优化(0.8-0.10)

    今天的内容包括建模优化 读写性能优化 xff0c 会涉及一些简单的原理介绍 主要面向 0 8 0 10 版本 正文 3754 字 xff0c 预计阅读时间 10 分钟 建模指南 关于存储组 现在每个存储组是一个相对独立的引擎 xff0c 而
  • Apache IoTDB 系列教程-8:文件同步工具

    在官网用户手册的系统工具 xff08 System Tools xff09 一栏 xff0c 有一个同步工具 xff08 Sync Tool xff09 xff0c 有很多人问这个东西怎么用 xff0c 延迟是多少 xff0c 今天就介绍一
  • Apache IoTDB failed to start RPC ServerService, because Could not create ServerSocket on address

    原因 一般是端口占用 xff0c 可以 jps 检查是不是已经启动了一个 IoTDB
  • Apache IoTDB Query is time out (-1ms)

    现象 查询超时 xff0c 服务器出现一下日志 2022 01 05 15 57 05 724 pool 12 IoTDB query time manager 1 WARN o a i d q c QueryTimeManager 71
  • 解读事务的ACID!

    事务的ACID特性大学数据库课程基本都学过 xff0c 但是学完也就大概知道是干嘛的 xff0c 后来也没仔细想这个东西了 xff0c 后来接触了NoSQL系统的一致性 xff0c 于是重新学习 ACID xff0c 发现还有很多误区 今天
  • 欢迎加入 Apache IoTDB !

    官方网站 xff1a http iotdb apache org zh IoTDB 是清华自研时间序列数据库 xff0c 2014年项目启动 xff0c 2018年11月18号 IoTDB 正式进入 Apache 孵化器 xff0c 成为中
  • Xavier(2):Xavier NX刷机步骤及报错解决

    1 下载和安装NVIDIA SDK Manager 官方网站 xff1a https developer nvidia com embedded jetpac 选择sdk manager xff0c sdk manager版本没有要求 安装
  • 模型评估与优化1--基本概念与最优化问题

    模型评估与优化1 基本概念与最优化问题 首先先看一下基本术语和概念 1 数据集的划分 xff08 1 xff09 数据集 dataset xff1a 在机器学习任务中使用的一组数据 数据集中每一个数据称为一个样本 反映样本在某方面的表现或性
  • windows中vscode编译运行c++程序

    1 vscode 安装 c 43 43 扩展 在vscode中创建一个后缀为 01 cpp 的程序 xff0c 程序文件如下 xff0c vscode会自动提示安装 c 43 43 扩展 xff0c 点击进行安装 01 cpp includ
  • leetcode 刷题指南 & 刷题顺序

    1 刷题方法 amp 顺序 xff1a 按类型刷 xff0c 这样能总结出每种类型题目的规律 优先树 链表 二分查找 DFS BFS 动态规划数目 xff1a 常见类型刷10道 43 顺序 xff1a 先做2 4道简单题 xff0c 然后做
  • 北邮计算机学院2017届复试经验分享

    北邮计算机学院2017届复试经验分享 建议初试完了再来担心复试 xff0c 有看复试经验的时间还不如多做两道数学题 xff01 导师 xff1a 了解导师的情况 xff0c 最差也不要找一个人不好的老师 xff0c 其次尽量选自己喜欢的方向
  • STM32 Cube BMP180 获取温度、气压、海拔

    一 介绍 BMP180中内置有E2PROM xff0c 所以要获取数据 xff0c 就要使用I2C读写E2PROM来实现获取数据 xff01 BMP180的整个流程 xff1a 1 首先要初始化 xff0c 读取几个E2PROM地址上的值共
  • int 类型究竟多少字节?

    今天发现NEON技术中 int类型的字节数是2 xff0c 感觉很奇怪 xff0c 最早写51单片机时也是2 xff0c 后来到了观念转变成了4 xff0c 现在有遇到了2 一 转自 http www tuicool com article
  • python实现K均值聚类算法

    之前做大作业的时候本来想用聚类法给点集分类的 xff0c 但是太复杂了 xff0c 于是最后没有采用这个方案 现在把之前做的一些工作整理出来写个小博客 K means聚类法原理 xff1a 聚类是一个将数据集中在某些方面相似的数据成员进行分
  • 复合型自适应步长的Gauss型求积(附代码)

    复合型自适应步长的Gauss型求积 先前在做数值分析实验时 xff0c 把高斯型求积公式和复合型 自适应步长的求积融合到了一起 xff0c 但是后来发现题目没有这个要求 现在就把这个思路分享一下 上题目 xff1a 实验目的 xff1a 学
  • pid摄像头循迹(opencv和openmv)

    pid摄像头循迹 xff08 opencv和openmv xff09 用摄像头进行循迹的方法参考硬件选型方面软件思路一 图像预处理 xff1a 代码部分二 线性拟合opencv线性拟合 xff1a 实际在树莓派上运行时 xff0c 帧率也比