11、使用OpenCV构建物体跟随机器人

使用OpenCV构建物体跟随机器人

1. 物体识别准备

在使用OpenCV进行物体识别时,我们可以通过以下步骤来识别图像中的彩色球。
- 拍摄合适的图像 :选择一个单色球(推荐红、绿、蓝单色球),将球放置在深色表面上(如果球是黑色或深色,则放在浅色表面),以确保球与背景有高对比度。拍摄时要避免球上有白色斑块,以免影响后续的阈值处理。拍摄满意的图像后,将其传输到笔记本电脑。
- 查找RGB像素值
1. 打开画图软件,导入保存的球的图像。
2. 使用颜色选取工具,点击球上的任意位置,“颜色1”框会显示所选颜色的样本。
3. 点击“编辑颜色”选项,查看该像素的RGB颜色值,并记录下来。
4. 重复此操作13 - 14次,确保涵盖球上最亮和最暗的颜色。标记出最低和最高的红、绿、蓝颜色值,后续用于图像阈值处理。
5. 将图像传输到树莓派(RPi),可以通过谷歌云端硬盘进行传输,具体步骤为:将图像上传到谷歌云端硬盘,在RPi中打开默认的Chromium网络浏览器,登录Gmail账户,打开谷歌云端硬盘并下载图像。

2. 物体检测程序

以下是用于检测绿色球的 ObjectDetection.cpp 程序:

#include <iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int main()
{
    Mat img, resizeimg,thresimage;
    img = imread("greenball.png");
    imshow("Green Ball Image", img);
    waitKey(0);
    resize(img, resizeimg, cvSize(640, 480));
    imshow("Resized Image", resizeimg);
    waitKey(0);
    inRange(resizeimg, Scalar(39, 140, 34), Scalar(122, 245, 119), thresimage);
    imshow("Thresholded Image", thresimage);
    waitKey(0);
    Moments m = moments(thresimage,true);
    int x,y;
    x = m.m10/m.m00;
    y = m.m01/m.m00;
    Point p(x,y);
    circle(img, p, 5, Scalar(0,0,200), -1);
    imshow("Image with center",img);
    waitKey(0);
    return 0;
}

该程序的详细解释如下:
1. 导入库和声明命名空间 :导入四个OpenCV库 opencv.hpp core.hpp highgui.hpp imgproc.hpp ,并声明 cv 命名空间。
2. 声明变量 :在 main 函数中,声明三个矩阵变量 img resizeimg thresimage
3. 读取图像 :使用 imread() 函数读取 greenball.png 文件,并将其存储在 img 变量中。
4. 显示图像 :使用 imshow() 函数显示图像,并使用 waitKey(0) 等待键盘输入。
5. 调整图像大小 :使用 resize() 函数将图像的宽度和高度调整为640x480。
6. 阈值处理 :使用 inRange() 函数进行阈值处理,将球的颜色变为白色,其余部分变为黑色。在 Scalar 函数中,先输入蓝色值,再输入绿色值,最后输入红色值。
7. 查找物体中心 :使用 moments() 函数查找物体的中心,并将其存储在 point 变量 p 中。
8. 显示中心点 :使用 circle() 函数在原始图像上显示一个红色圆点,表示球的中心。
9. 关闭窗口 :再次按下任意键, waitKey(0) 函数将关闭所有窗口(除终端窗口外),按回车键关闭终端窗口。

3. OpenCV相机视频流程序

以下是用于查看树莓派相机视频流的 Camerafeed.cpp 程序:

int main()
{
    Mat videoframe;
    VideoCapture vid(0);
    if (!vid.isOpened())
    {
        cout<<"Error opening camera"<<endl;
        return -1;
    }
    for(;;)
    {
        vid.read(videoframe);
        imshow("Frame", videoframe);
        if (waitKey(1) > 0) break;
    }
    return 0;
}

该程序的详细解释如下:
1. 声明变量 :在 main 函数中,声明一个矩阵变量 videoframe
2. 捕获视频流 :使用 VideoCapture 数据类型捕获树莓派相机的视频流, vid(0) 中的0表示相机的索引编号。如果连接了USB相机,其索引编号为1。
3. 检查相机状态 :如果相机无法捕获视频流,将输出“Error opening camera”消息。
4. 读取视频帧 :使用 vid.read(videoframe) 命令读取相机视频流。
5. 显示视频帧 :使用 imshow() 函数显示视频帧。
6. 等待键盘输入 :使用 waitKey 命令等待键盘输入,按下任意键将退出程序。

4. 构建物体跟踪机器人
4.1 球跟踪的编程逻辑

在让机器人跟随球之前,需要先让机器人能够使用树莓派相机跟踪球。具体步骤如下:
- 调整相机分辨率 :将相机分辨率调整为640x480。
- 划分相机屏幕 :将相机屏幕水平划分为三个相等的部分:
- x坐标值从0到214表示左部分。
- x坐标值从214到428表示前部分。
- x坐标值从428到640表示右部分。
- 阈值处理和查找中心 :对球进行阈值处理,使用 moments 函数在球的中心生成一个圆点,并在控制台打印该点的值。如果球在前部分,x坐标值必须在214到428之间。

4.2 球跟踪程序

以下是 BallTracing.cpp 程序:

int main()
{
    Mat videofeed,resizevideo,thresholdvideo;
    VideoCapture vid(0);
    if (!vid.isOpened())
    {
        return -1;
    }
    for (;;)
    {
        vid.read(videofeed);
        resize(videofeed, resizevideo, cvSize(640, 480));
        flip(resizevideo, resizevideo, 1);
        inRange(resizevideo, Scalar(39, 140, 34), Scalar(122, 245, 119), thresholdvideo);
        Moments m = moments(thresholdvideo,true);
        int x,y;
        x = m.m10/m.m00;
        y = m.m01/m.m00;
        Point p(x,y);
        circle(resizevideo, p, 10, Scalar(0,0,128), -1);
        imshow("Image with center",resizevideo);
        imshow("Thresolding Video",thresholdvideo);
        cout<<Mat(p)<< endl;
        if (waitKey(33) >= 0) break;
    }
    return 0;
}

该程序的详细解释如下:
1. 声明变量 :在 main 函数中,声明三个矩阵变量 videofeed resizevideo thresholdvideo ,并声明一个 VideoCapture 变量 vid(0) 用于捕获视频。
2. 读取视频流 :在 for 循环中,使用 vid.read(videofeed) 代码读取相机视频流。
3. 调整视频大小 :使用 resize() 函数将相机分辨率调整为640x480,并将调整后的视频流存储在 resizevideo 变量中。
4. 翻转图像 :使用 flip() 函数将调整后的图像水平翻转,以避免球的移动方向与实际方向相反。
5. 阈值处理 :使用 inRange() 函数对视频流进行阈值处理,将球的颜色突出显示。
6. 查找球的中心 :使用 moments() 函数查找球的中心,并将其存储在 point 变量 p 中。
7. 显示中心点 :使用 circle() 函数在调整后的视频流中显示一个红色圆点。
8. 显示视频流 :使用 imshow() 函数显示调整后的视频流和阈值处理后的视频流。
9. 打印坐标值 :使用 cout<<Mat(p)<<endl; 代码在控制台显示红色圆点的x和y坐标值。

5. 设置物体跟随机器人

在跟踪球的位置后,需要让机器人跟随球。为了确保机器人与球保持适当的距离,避免碰撞,我们需要在机器人上安装超声波传感器。将超声波传感器的触发引脚连接到wiringPi引脚12,回声引脚通过分压电路连接到wiringPi引脚13。

6. 物体跟随机器人程序

以下是 ObjectFollowingRobot.cpp 程序:

int main()
{
    ...
    float distance = (totalTime * 0.034)/2;
    if(distance < 15)
    {
        cout<<"Object close to Robot"<< " " << Mat(p)<< " " <<distance << " cm" << endl;
        stop();
    }
    else{
        if(x<20 && y< 20)
        {
            cout<<"Object not found"<< " " << Mat(p)<< " " <<distance << " cm" << endl;
            stop();
        }
        if(x > 20 && x < 170 && y > 20 )
        {
            cout<<"LEFT TURN"<< " " << Mat(p)<< " " <<distance << " cm" << endl;
            left();
        }
        if(x > 170 && x < 470)
        {
            cout<<"FORWARD"<< " " << Mat(p)<< " " <<distance << " cm" << endl;
            forward();
        }
        if(x > 470 && x < 640)
        {
            cout<<"RIGHT TURN"<< " " << Mat(p)<< " " <<distance << " cm" << endl;
            right();
        }
    }
    if (waitKey(33) >= 0) break;
    return 0;
}

该程序的详细解释如下:
1. 计算距离 :使用超声波传感器计算机器人与物体之间的距离。
2. 检查距离 :如果距离小于15cm,机器人将停止,并输出“Object close to Robot”消息。
3. 检查物体位置 :如果距离大于15cm,根据红色圆点的位置,机器人将执行相应的动作:
- 如果x和y坐标值都小于20,机器人将停止,并输出“Object not found”消息。
- 如果x坐标值在20到170之间,且y坐标值大于20,机器人将左转。
- 如果x坐标值在170到470之间,机器人将前进。
- 如果x坐标值在470到640之间,机器人将右转。

使用移动电源为机器人供电,使其能够自由移动。编译程序并将其构建在树莓派机器人上。只要球不在机器人前方,红色圆点将停留在屏幕的左上角,机器人不会移动。如果将球移到相机前方,且与机器人的距离大于15cm,机器人将开始跟随球。

在机器人跟随球的过程中,由于外部因素(如阳光或室内光线)的影响,球的颜色可能会发生变化,导致阈值处理不正常,机器人可能无法顺利跟随球。在这种情况下,需要调整RGB值。

通过以上步骤,我们可以使用OpenCV和超声波传感器来检测球并让机器人跟随它。未来,我们可以进一步扩展OpenCV知识,例如使用Haar级联检测人脸,识别微笑并让机器人跟随人脸。

以下是整个流程的mermaid流程图:

graph LR
    A[拍摄球的图像] --> B[查找RGB像素值]
    B --> C[物体检测程序]
    C --> D[OpenCV相机视频流程序]
    D --> E[球跟踪程序]
    E --> F[设置物体跟随机器人]
    F --> G[物体跟随机器人程序]

以下是相机屏幕划分的表格:
| 区域 | x坐标范围 | 机器人动作 |
| ---- | ---- | ---- |
| 左部分 | 0 - 214 | 左转 |
| 前部分 | 214 - 428 | 前进 |
| 右部分 | 428 - 640 | 右转 |

使用OpenCV构建物体跟随机器人

7. 总结与展望

在前面的内容中,我们详细介绍了如何使用OpenCV构建一个物体跟随机器人。首先,我们学习了OpenCV库中的一些重要函数,通过这些函数实现了从图像中识别物体的功能。具体操作步骤包括拍摄合适的球的图像、查找其RGB像素值、编写物体检测程序、查看相机视频流、跟踪球以及让机器人跟随球。

下面我们对整个过程的关键步骤进行梳理:
1. 图像准备与处理
- 拍摄球的图像,确保球与背景有高对比度,避免球上有白色斑块。
- 使用画图软件查找球的RGB像素值,记录最低和最高的红、绿、蓝颜色值。
- 将图像传输到树莓派,用于后续处理。
2. 程序编写与实现
- 编写物体检测程序,对图像进行读取、调整大小、阈值处理和中心点标记。
- 编写相机视频流程序,实现对树莓派相机视频流的读取和显示。
- 编写球跟踪程序,对视频流进行处理,找到球的中心并标记。
- 编写物体跟随机器人程序,结合超声波传感器,根据球的位置和距离控制机器人的动作。

在实际应用中,可能会遇到一些问题。例如,由于外部光线的影响,球的颜色可能会发生变化,导致阈值处理不正常,机器人无法顺利跟随球。此时,需要根据实际情况调整RGB值,以保证机器人的正常运行。

未来,我们可以进一步扩展OpenCV的应用。例如,使用Haar级联检测人脸,识别微笑并让机器人跟随人脸。这将为机器人的应用场景带来更多的可能性,如服务型机器人在与人交互时能够更好地跟踪和响应人的动作。

以下是整个过程的关键步骤列表:
1. 拍摄球的图像
2. 查找RGB像素值
3. 编写物体检测程序
4. 编写相机视频流程序
5. 编写球跟踪程序
6. 设置物体跟随机器人
7. 编写物体跟随机器人程序
8. 调整RGB值(根据实际情况)
9. 扩展应用(如检测人脸、识别微笑)

以下是不同程序的功能和作用表格:
| 程序名称 | 功能 | 作用 |
| ---- | ---- | ---- |
| ObjectDetection.cpp | 对图像进行处理,找到球的中心并标记 | 识别图像中的球 |
| Camerafeed.cpp | 读取和显示树莓派相机的视频流 | 查看相机视频 |
| BallTracing.cpp | 对视频流进行处理,找到球的中心并标记 | 跟踪球的位置 |
| ObjectFollowingRobot.cpp | 根据球的位置和距离控制机器人的动作 | 让机器人跟随球 |

通过以上的总结和分析,我们对使用OpenCV构建物体跟随机器人有了更深入的理解。希望这些内容能够帮助你在实际项目中更好地应用OpenCV和机器人技术。

以下是扩展应用的mermaid流程图:

graph LR
    H[当前物体跟随机器人] --> I[使用Haar级联检测人脸]
    I --> J[识别微笑]
    J --> K[机器人跟随人脸]

通过这个流程图,我们可以清晰地看到未来扩展应用的步骤和方向。从当前的物体跟随机器人,进一步发展到检测人脸、识别微笑并让机器人跟随人脸,这将为机器人的智能化和交互性带来更大的提升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值