使用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[机器人跟随人脸]
通过这个流程图,我们可以清晰地看到未来扩展应用的步骤和方向。从当前的物体跟随机器人,进一步发展到检测人脸、识别微笑并让机器人跟随人脸,这将为机器人的智能化和交互性带来更大的提升。
超级会员免费看
1019

被折叠的 条评论
为什么被折叠?



