Blogger Information
Blog 291
fans 0
comment 0
visits 349743
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
【Linux学习】OpenCV+ROS 实现人脸识别(Ubantu16.04)
Original
635 people have browsed it

镜像下载、域名解析、时间同步请点击 阿里云开源镜像站

前言

本文主要学习 ROS机器人操作系统 ,在ROS系统里调用 OpenCV库 实现人脸识别任务

一、环境配置

1.安装ROS

  1. sudo apt-get install ros-kinetic-desktop-full

2.摄像头调用

安装摄像头组件相关的包,命令行如下:

  1. sudo apt-get install ros-kinetic-usb-cam

启动摄像头,命令行如下:

  1. roslaunch usb_cam usb_cam-test.launch

调用摄像头成功,如下图所示:

file

摄像头的驱动发布的相关数据,如下图所示:

file

摄像头 usb_cam/image_raw 这个话题,发布的消息的具体类型,如下图所示:

file

那么图像消息里面的成员变量有哪些呢?

打印一下就知道了!一个消息类型里面的具体成员变量,如下图所示:

file

  • Header:很多话题消息里面都包含的

    消息头:包含消息序号,时间戳和绑定坐标系

    消息的序号:表示我们这个消息发布是排第几位的,并不需要我们手动去标定,每次

    发布消息的时候会自动地去累加

    绑定坐标系:表示的是我们是针对哪一个坐标系去发布的header有时候也不需要去配置

  • height:图像的纵向分辨率

  • width:图像的横向分辨率

  • encoding:图像的编码格式,包含RGB、YUV等常用格式,都是原始图像的编码格式,不涉及图像压缩编码

  • is_bigendian: 图像数据的大小端存储模式

  • step:一行图像数据的字节数量,作为数据的步长参数

  • data:存储图像数据的数组,大小为step×height个字节

  • format:图像的压缩编码格式(jpeg、png、bmp)

3.导入OpenCV

file

在ROS当中完成OpenCV的安装,命令行如下图所示:

  1. sudo apt-get install ros-kinetic-vision-opencv libopencv-dev python-opencv

安装完成

file

二、创建工作空间和功能包

1.创建工作空间

  1. mkdir -p ~/catkin_ws/src
  2. cd ~/catkin_ws/src
  3. catkin_init_workspace
  • 创建完成工作空间后,在根目录下面,执行编译整个工作空间
  1. cd ~/catkin_ws/
  2. catkin_make
  • 工作空间中会自动生成两个文件夹:devel,build

  • devel文件夹中产生几个setup.*sh形成的环境变量设置脚本,使用source命令运行这些脚本文件,则工作空间中的环境变量得以生效

  1. source devel/setup.sh
  • 将环境变量设置到/.bashrc文件中
  1. gedit ~/.bashrc
  • 在打开的文件,最下面粘贴以下代码即可设置环境变量
  1. source ~/catkin_ws/devel/setup.bash

2.创建功能包

开始创建

  1. cd ~/catkin_ws/src
  2. catkin_create_pkg learning std_msgs rospy roscpp

回到根目录,编译并设置环境变量

  1. cd ~/catkin_ws
  2. catkin_make
  3. source ~/catkin_ws/devel/setup.sh

三、人脸识别检测相关代码

基于 Haar 特征的级联分类器检测算法

核心内容,如下所示:

  • 灰阶色彩转换
  • 缩小摄像头图像
  • 直方图均衡化
  • 检测人脸

1.python文件

face_detector.py

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import rospy
  4. import cv2
  5. import numpy as np
  6. from sensor_msgs.msg import Image, RegionOfInterest
  7. from cv_bridge import CvBridge, CvBridgeError
  8. class faceDetector:
  9. def __init__(self):
  10. rospy.on_shutdown(self.cleanup);
  11. # 创建cv_bridge
  12. self.bridge = CvBridge()
  13. self.image_pub = rospy.Publisher("cv_bridge_image", Image, queue_size=1)
  14. # 获取haar特征的级联表的XML文件,文件路径在launch文件中传入
  15. cascade_1 = rospy.get_param("~cascade_1", "")
  16. cascade_2 = rospy.get_param("~cascade_2", "")
  17. # 使用级联表初始化haar特征检测器
  18. self.cascade_1 = cv2.CascadeClassifier(cascade_1)
  19. self.cascade_2 = cv2.CascadeClassifier(cascade_2)
  20. # 设置级联表的参数,优化人脸识别,可以在launch文件中重新配置
  21. self.haar_scaleFactor = rospy.get_param("~haar_scaleFactor", 1.2)
  22. self.haar_minNeighbors = rospy.get_param("~haar_minNeighbors", 2)
  23. self.haar_minSize = rospy.get_param("~haar_minSize", 40)
  24. self.haar_maxSize = rospy.get_param("~haar_maxSize", 60)
  25. self.color = (50, 255, 50)
  26. # 初始化订阅rgb格式图像数据的订阅者,此处图像topic的话题名可以在launch文件中重映射
  27. self.image_sub = rospy.Subscriber("input_rgb_image", Image, self.image_callback, queue_size=1)
  28. def image_callback(self, data):
  29. # 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
  30. try:
  31. cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
  32. frame = np.array(cv_image, dtype=np.uint8)
  33. except CvBridgeError, e:
  34. print e
  35. # 创建灰度图像
  36. grey_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  37. # 创建平衡直方图,减少光线影响
  38. grey_image = cv2.equalizeHist(grey_image)
  39. # 尝试检测人脸
  40. faces_result = self.detect_face(grey_image)
  41. # 在opencv的窗口中框出所有人脸区域
  42. if len(faces_result)>0:
  43. for face in faces_result:
  44. x, y, w, h = face
  45. cv2.rectangle(cv_image, (x, y), (x+w, y+h), self.color, 2)
  46. # 将识别后的图像转换成ROS消息并发布
  47. self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
  48. def detect_face(self, input_image):
  49. # 首先匹配正面人脸的模型
  50. if self.cascade_1:
  51. faces = self.cascade_1.detectMultiScale(input_image,
  52. self.haar_scaleFactor,
  53. self.haar_minNeighbors,
  54. cv2.CASCADE_SCALE_IMAGE,
  55. (self.haar_minSize, self.haar_maxSize))
  56. # 如果正面人脸匹配失败,那么就尝试匹配侧面人脸的模型
  57. if len(faces) == 0 and self.cascade_2:
  58. faces = self.cascade_2.detectMultiScale(input_image,
  59. self.haar_scaleFactor,
  60. self.haar_minNeighbors,
  61. cv2.CASCADE_SCALE_IMAGE,
  62. (self.haar_minSize, self.haar_maxSize))
  63. return faces
  64. def cleanup(self):
  65. print "Shutting down vision node."
  66. cv2.destroyAllWindows()
  67. if __name__ == '__main__':
  68. try:
  69. # 初始化ros节点
  70. rospy.init_node("face_detector")
  71. faceDetector()
  72. rospy.loginfo("Face detector is started..")
  73. rospy.loginfo("Please subscribe the ROS image.")
  74. rospy.spin()
  75. except KeyboardInterrupt:
  76. print "Shutting down face detector node."
  77. cv2.destroyAllWindows()

2.lanuch文件

usb_cam.launch

  • 摄像头启动文件
  1. <launch>
  2. <node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
  3. <param name="video_device" value="/dev/video0" />
  4. <param name="image_width" value="640" />
  5. <param name="image_height" value="480" />
  6. <param name="pixel_format" value="yuyv" />
  7. <param name="camera_frame_id" value="usb_cam" />
  8. <param name="io_method" value="mmap"/>
  9. </node>
  10. </launch>

face_detector.launch

  • 人脸识别启动文件
  1. <launch>
  2. <node pkg="test2" name="face_detector" type="face_detector.py" output="screen">
  3. <remap from="input_rgb_image" to="/usb_cam/image_raw" />
  4. <rosparam>
  5. haar_scaleFactor: 1.2
  6. haar_minNeighbors: 2
  7. haar_minSize: 40
  8. haar_maxSize: 60
  9. </rosparam>
  10. <param name="cascade_1" value="$(find robot_vision)/data/haar_detectors/haarcascade_frontalface_alt.xml" />
  11. <param name="cascade_2" value="$(find robot_vision)/data/haar_detectors/haarcascade_profileface.xml" />
  12. </node>
  13. </launch>

3.CvBridge

  • ROS 与 OpenCV 之间的数据连接是通过 CvBridge 来实现的
  • ROS Image Message与 OpenCV Ipllmage 之间连接的一个桥梁

cv_bridge_test.py

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import rospy
  4. import cv2
  5. from cv_bridge import CvBridge, CvBridgeError
  6. from sensor_msgs.msg import Image
  7. class image_converter:
  8. def __init__(self):
  9. # 创建cv_bridge,声明图像的发布者和订阅者
  10. self.image_pub = rospy.Publisher("cv_bridge_image", Image, queue_size=1)
  11. self.bridge = CvBridge()
  12. self.image_sub = rospy.Subscriber("/usb_cam/image_raw", Image, self.callback)
  13. def callback(self,data):
  14. # 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
  15. try:
  16. cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
  17. except CvBridgeError as e:
  18. print e
  19. # 在opencv的显示窗口中绘制一个圆,作为标记
  20. (rows,cols,channels) = cv_image.shape
  21. if cols > 60 and rows > 60 :
  22. cv2.circle(cv_image, (60, 60), 30, (0,0,255), -1)
  23. # 显示Opencv格式的图像
  24. cv2.imshow("Image window", cv_image)
  25. cv2.waitKey(3)
  26. # 再将opencv格式额数据转换成ros image格式的数据发布
  27. try:
  28. self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
  29. except CvBridgeError as e:
  30. print e
  31. if __name__ == '__main__':
  32. try:
  33. # 初始化ros节点
  34. rospy.init_node("cv_bridge_test")
  35. rospy.loginfo("Starting cv_bridge_test node")
  36. image_converter()
  37. rospy.spin()
  38. except KeyboardInterrupt:
  39. print "Shutting down cv_bridge_test node."
  40. cv2.destroyAllWindows()

四、代码实测

1.执行命令行

分别在三个终端下运行,命令行如下:

启动摄像头

  1. roslaunch robot_vision usb_cam.launch

启动人脸识别

  1. roslaunch robot_vision face_detector.launch

打开人脸识别窗口

  1. rqt_image_view

2.人脸识别效果

拿了C站官方送的书来进行测试,识别的效果还是相当不错的,效果如下图所示:

file

五、报错解决

报错1:E:无法定位软件包 ros-kinetic-usb-cam

file

解决方法: 网上下载编译安装

$ cd catkin_ws/src

$ git clone https://github.com/bosch-ros-pkg/usb_cam.git

$ cd ~/catkin_ws

$ catkin_make

成功解决:

file

报错2:启动摄像头报错

file

file决方法:输入以下命令行,再启动摄像头

  1. source ~/catkin_ws/devel/setup.bash

成功解决:

file

报错3:虚拟机摄像头没连接报错

file

解决方法:打开虚拟机设置,更改usb版本为3.1

file

可移动设备将摄像头设置连接

file

六、总结

  • 在ROS操作系统中调用 OpenCV 完成人脸识别还是比较有意思的,目前图像处理和人脸识别还是比较常用到的,本文主要记录学习过程,以及遇到的相关报错问题进行记录

  • 如何对于特定目标的检测并显示出结果?如何优化让人脸识别的更精准?目前还在朝着这个方向进行思考和探究

原文链接:https://blog.csdn.net/m0_61745661/article/details/125578352

Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post