第八章作业
第一题 安装ROS摄像头驱动功能包,驱动笔记本摄像头,并使用ROS可视化工具显示图像
1.1 安装驱动功能包
ROS中有通用USB摄像头的驱动功能包——usb_cam,安装后很快就可以把摄像头跑起来,在该功能包的wiki上我们可以看到详细的接口说明,最终的图像将通过<camera_name>/image发布出来,订阅后就可以看到图像了。
在终端输入依次输入:

sudo apt-get install ros-melodic-usb-cam
roslaunch usb_cam usb_cam-test.launch
rqt_image_view

第一条命令是安装摄像头的驱动,第二条命令是启动摄像头程序,第三条命令是测试摄像头能否正常使用。效果如图1-1所示。

Opencv pynput 在机械臂上的应用 opencv识别物体机械臂抓取_可视化工具

图1-1 驱动摄像头

第二题 识别白色物体,将其边缘绘制出来,并在ROS中显示识别结果

ROS本身并没有图形处理能力,需要借助OpenCV等开源库实现,由于不同库中的图像数据定义不同,ROS定义了一个“Bridge”来做桥接,CvBridge就是完成ROS图像消息和OpenCV图像数据转换的“桥”。如图2-1所示。

Opencv pynput 在机械臂上的应用 opencv识别物体机械臂抓取_数据_02

图2-1 ROS与OpenCV的集成框架

2.1 OpenCV库

OpenCV库是一个基于BSD许可发行的跨平台开源计算机视觉库,可以直接访问硬件摄像头,并且还提供一个简单的GUI系统——highgui。基于OpenCV库,我们可以快速开发机器视觉方面的应用,而且ROS中 已经集成了OpenCV库和相关的接口功能包,使用以下命令即可安装:Sudo apt-get install ros-melodic-vision-opencv libpencv-dev python-opencv。

2.2 在ROS中使用OpenCV

在终端输入roslaunch probot_gazebo probot_anno_with_gripper_ gazebo_world.launch、rosrun probot_vision vision_manager以及rqt_ image_view。即可得到如图2-2所示内容。(内容都是修改过的,命令没变)

Opencv pynput 在机械臂上的应用 opencv识别物体机械臂抓取_OpenCV_03

图2-2 物体识别

下面分析实现该程序的关键部分

image_sub_ = it_.subscribe("/probot_anno/camera/image_raw", 1, &VisionManager::imageCb, this);
image2_pub_ = it_.advertise("/table_detect", 1);

首先定义一个Subscriber接收原始图像消息,再定义一个Publisher发布OpenCV处理后的图像消息。

try
cv_ptr_ = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
catch (cv_bridge::Exception &e)
ROS_ERROR("cv_bridge exception: %s", e.what());
return;

然后利用CvBridge功能将ROS图像消息转换成OpenCV图像数据。

cv::Mat binaryImage = denoiseImage;
for (int i = 0; i < binaryImage.rows; i++)
for (int j = 0; j < binaryImage.cols; j++)
int editValue = binaryImage.at<uchar>(i, j);
int editValue2 = gray_image_green.at<uchar>(i, j);
if ((editValue >= 0) && (editValue < 50) && (editValue2 >= 0) && (editValue2 < 20))
{ // check whether value is within range.
binaryImage.at<uchar>(i, j) = 0;
else
binaryImage.at<uchar>(i, j) = 255;

再就是利用OpenCV中的算法对从ROS中转换过来的图像进行处理了,主要是通过图像通道的分离和阈值判断识别不同的颜色来确定物体的像素位置,再通过一个简单的线性变换计算图像坐标系下的实际位置。

// Output modified video stream
image1_pub_.publish(cv_ptr_->toImageMsg());

最后将OpenCV的图像转换成ROS图像消息发布出来,就可以再ROS中看到结果了。