机器人视觉是机器人应用中至关重要的一部分,获取机 器人的视觉图像及进行人脸识别是很多应用的基础。

一、 在仿真环境中获取机器人平面视觉图像

1.编写节点代码
首先需要创建一个ROS源码包。在Ubuntu里打开一个终端程序,输入如下指令进入ROS工作空间。
cd catkin_ws/src/

然后输入如下指令创建ROS源码包。
catkin_create_pkg image_pkg rospy std_msgs sensor_msgs cv_bridge
按“Enter”键后创建image_pkg源码包

新建文件夹,命名为“scripts”;后“新建文件”,这个Python节点文件被命名为“image_node.py”。

命名完成后即可在IDE右侧开始编写“image_node.py”的代码,其内容如下

#!/usr/bin/env python3
# coding=utf-8
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
capture_one_frame = True

# 彩色图像回调函数
def cbImage(msg):
bridge = CvBridge()
cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")

弹出窗口显示图片

cv2.imshow("Image window", cv_image)
cv2.waitKey(1)
# 保存图像到文件
global capture_one_frame
if capture_one_frame == True:
cv2.imwrite('/home/robot/1.jpg', cv_image)
rospy.logwarn("保存图片成功!")
capture_one_frame = False

# 主函数
if __name__ == "__main__":
rospy.init_node("image_node")

订阅机器人视觉传感器kinect2的图像话题

image_sub = rospy.Subscriber("/kinect2/hd/image_color_rect",Image, cbImage,queue_size=10)
rospy.spin()

这里使用import导入以下五个模块。

① rospy模块,包含了大部分的ROS接口函数。
② cv2模块,包含了OpenCV图形处理库的函数接口。
③ sensor_msgs.msg里的Image数据类型模块,这个是ROS里常用的图形数据类型。
④ cv_bridge里的CvBridge模块,这个是ROS图形数据格式和OpenCV图像数据格式的转换工具。
⑤ cv_bridge里的CvBridgeError模块,用于处理图像格式转换过程中的一些异常错误。

按下“Ctrl+S”键进行保存

2. 由于这个代码文件是新创建的,其默认不带有可执行属性,所以我们需要为其添加一个可执行属性才能让它运行起来。启动一个终端程序,输入如下指令进入这个代码文件所存放的目录。
cd ~/catkin_ws/src/image_pkg/scripts/
再执行如下指令为代码文件添加可执行属性。
chmod +x image_node.py

3.编译软件包
现在节点文件可以运行了,但是这个软件包还没有加入ROS的包管理系统,无法通过ROS指令运行其中的节点,因此还需要对这个软件包进行编译。在终端程序中输入如下指令进入ROS工作空间。
cd ~/catkin_ws/
再执行如下指令对软件包进行编译。
catkin_make

4.启动仿真环境
启动开源项目“wpr_simulation”中的仿真场景,打开终端程序,输入如下指令。
roslaunch wpr_simulation wpb_single_face.launch
启动后会弹出仿真场景,机器人前方站立着一个模型。

5.运行节点程序
启动image_node节点,打开一个新的终端程序,输入如下指令。
rosrun image_pkg image_node.py
指令运行后会在主目录下生成一个新的jpg图像文件,如果发现没有新文件生成,那么请查看终端程序内@符号前的用户名和程序内设置的保存路径,将程序内的用户名更改成终端程序内显示的用户名即可

二、 利用平面视觉进行人脸检测

1.编写节点代码
首先需要创建一个ROS源码包Package。在Ubuntu里打开一个终端程序,输入如下指令进入ROS工作空间
cd catkin_ws/src/

然后输入如下指令创建ROS源码包。
catkin_create_pkg face_pkg rospy std_msgs sensor_msgs cv_bridge
按“Enter”键创建face_pkg源码包,系统会提示ROS源码包创建成功,这时可以看到“catkin_ws/src”目录下出现了“face_pkg”子目录。
接下来在Visual Studio Code中进行操作,将目录展开,找到前面新建的“image_pkg”并展开,可以看到这是一个功能包最基础的结构,选中“image_pkg”并右击,选择“新建文件夹”。

将这个文件夹命名为“scripts”。
选中此文件夹并对其右击,选择“新建文件”。将这个Python节点文件命名为“face_node.py”。

#!/usr/bin/env python3
# coding=utf-8
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
# 彩色图像回调函数
def cbImage(msg):
bridge = CvBridge()
cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
#转换为灰度图
gray_img=cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)

#创建一个级联分类器
face_casecade = cv2.CascadeClassifier('/home/robot/catkin_ws/src/wpb_home/
wpb_home_python/config/haarcascade_frontalface_alt.xml’)
#人脸检测
face = face_casecade.detectMultiScale(gray_img, 1.3, 5)
for (x,y,w,h) in face:
#在原图上绘制矩形
cv2.rectangle(cv_image,(x,y),(x+w,y+h),(0,0,255),3)
rospy.loginfo("人脸位置 = (%d,%d) ",x,y)

弹出窗口显示图片

cv2.imshow("face window", cv_image)
cv2.waitKey(1)

# 主函数
if __name__ == "__main__":
rospy.init_node("image_face_detect")

订阅机器人视觉传感器kinect2的图像话题

image_sub = rospy.Subscriber("/kinect2/hd/image_color_rect",Image,
cbImage,queue_size=10)
rospy.spin()

使用import导入以下五个模块。
① rospy模块,包含了大部分的ROS接口函数。
② cv2模块,包含了OpenCV图形处理库的函数接口。
③ sensor_msgs.msg里的Image数据类型,这个是ROS里常用的图形数据类型。
④ cv_bridge里的CvBridge,这个是ROS图形数据格式和OpenCV图像数据格式的转换工具。
⑤ cv_bridge里的CvBridgeError,用于处理图像格式转换过程中的一些异常错误。

定义一个回调函数cbImage(),用来处理kinect2获取到的彩色视频图像。ROS每接收到一帧传回来的彩色视频图像,就会自动调用一次回调函数。图像数据会以参数的形式传递到这个回调函数里。

回调函数cbImage()的参数msg是一个sensor_msgs::Image格式的消息包,其中存放着ROS格式的彩色图像数据。在实际开发中,通常不会直接使用这个格式的图像,而是将其转换成OpenCV格式,这样就可以使用丰富的OpenCV函数来处理彩色图像。

下面开始这个转换操作,先生成一个CvBridge对象,对象名为“bridge”;然后调用bridge的imgmsg_to_cv2()函数,将参数msg里的图像数据转换成OpenCV的bgr8格式,并保存在对象cv_image中。

调用cv2的cvtColor()函数将彩色图像cv_image转换成黑白灰度图,并存放在gray_img里。

调用cv2的CascadeClassifier()函数构造一个级联分类器,名字叫face_casecade。分类器的参数从一个xml文件里读取,这个文件在另外的wpb_home源码目录中,这个源码应该在安装系统时已经部署好了,如果Ubuntu用户名不为“robot”请将其更改为正确的用户名。

调用face_casecade分类器的detectMultiScale()函数,从黑白灰度图gray_img中检测人脸,并将检测结果放置在face数组中。参数1.3是每次搜索人脸目标的缩放比例,参数5是构成目标的相邻矩形的最小个数。参数的具体意义可以查阅detectMultiScale()函数的官方说明,这里使用这两个数值就行。

使用for循环将face里的人脸检测结果逐个提取出来。每个检测结果包含如下数值。
① x为人脸目标在图像中的横向坐标最小值,单位是像素,越小越靠近左侧。
② y为人脸目标在图像中的纵向坐标最小值,单位是像素,越小越靠近上方。
③ w为人脸目标的横向宽度,单位是像素。
④ h为人脸目标的纵向宽度,单位是像素。
对于每一个人脸检测结果,系统都会先调用cv2的rectangle()函数在彩色图像cv_image上绘制一个对应的矩形框;然后使用rospy.loginfo()函数将人脸位置矩形框的左上角坐标值显示在终端里。

在按下“Ctrl+S”键进行保存后

2.设置可执行权限
由于这个代码文件是新创建的,其默认不带有可执行属性,所以我们需要为其添加一个可执行属性才能让它运行起来。启动一个终端程序,输入如下指令进入这个代码文件所存放的目录。
cd ~/catkin_ws/src/face_pkg/scripts/

再执行如下指令为代码文件添加可执行属性。
chmod +x face_node.py

3.编译软件包
现在节点文件可以运行了,但是这个软件包还没有加入ROS的包管理系统,无法通过ROS指令运行其中的节点,因此还需要对这个软件包进行编译。在终端程序中输入如下指令进入ROS工作空间。
cd ~/catkin_ws/

再执行如下指令对软件包进行编译。

catkin_make
编译完成就可以测试此节点了

4 启动仿真环境
启动开源项目“wpr_simulation”中的仿真场景,打开终端程序,输入如下指令。
roslaunch wpr_simulation wpb_single_face.launch

5.运行节点程序
运行face_node节点,需要注意的是,在程序中读取文件的Ubuntu系统用户名一定要设置正确,否则运行此节点将报错。打开一个新的终端程序,输入如下指令。
rosrun face_pkg face_node.py
启动image_node节点

运行后可以看到终端程序中显示检测到的人脸坐标信息。终端程序人脸识别结果如图所示。

来源: 部分来自网络