• 【Linux学习】OpenCV+ROS 实现人脸识别(Ubantu16.04)


    目录

    前言

    一、环境配置  

    1.安装ROS 

    2.摄像头调用

    3.导入OpenCV

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

    1.创建工作空间

    2.创建功能包

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

    1.python文件

    2.lanuch文件 

    3.CvBridge

    四、代码实测

    1.执行命令行 

    2.人脸识别效果

    五、报错解决

    六、总结


    前言

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

    一、环境配置  

    1.安装ROS 

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

    如果ROS还不懂如何安装的,可以看下这一篇:【Linux学习】虚拟机VMware 安装ROS 一条龙教程+部分报错解决_猿力猪的博客-CSDN博客_ros vmwareLinux下载安装ROS,一条龙详解!希望对您有所帮助!https://blog.csdn.net/m0_61745661/article/details/124534353

    2.摄像头调用

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

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

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

    roslaunch usb_cam usb_cam-test.launch

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

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

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

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

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

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

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

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

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

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

    • height:图像的纵向分辨率
    • width:图像的横向分辨率
    • encoding:图像的编码格式,包含RGB、YUV等常用格式,都是原始图像的编码格式,不涉及图像压缩编码
    • is_bigendian: 图像数据的大小端存储模式
    • step:一行图像数据的字节数量,作为数据的步长参数
    • data:存储图像数据的数组,大小为step×height个字节
    • format:图像的压缩编码格式(jpeg、png、bmp)

    3.导入OpenCV

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

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

    安装完成 

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

    1.创建工作空间

    1. mkdir -p ~/catkin_ws/src
    2. cd ~/catkin_ws/src
    3. catkin_init_workspace
    • 创建完成工作空间后,在根目录下面,执行编译整个工作空间  
    1. cd ~/catkin_ws/
    2. catkin_make
    • 工作空间中会自动生成两个文件夹:develbuild
    • devel文件夹中产生几个setup.*sh形成的环境变量设置脚本,使用source命令运行这些脚本文件,则工作空间中的环境变量得以生效 
    source devel/setup.sh
    
    •  将环境变量设置到/.bashrc文件
    gedit ~/.bashrc
    
    • 在打开的文件,最下面粘贴以下代码即可设置环境变量 
    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.执行命令行 

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

    • 启动摄像头 
    roslaunch robot_vision usb_cam.launch
    
    • 启动人脸识别
    roslaunch robot_vision face_detector.launch
    
    • 打开人脸识别窗口
    rqt_image_view

    2.人脸识别效果

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

    五、报错解决

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

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

    $ cd catkin_ws/src
    $ git clone https://github.com/bosch-ros-pkg/usb_cam.git
    $ cd ~/catkin_ws
    $ catkin_make

    成功解决: 

    报错2:启动摄像头报错

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

    source ~/catkin_ws/devel/setup.bash

    成功解决: 

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

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

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

    六、总结 

    • 在ROS操作系统中调用 OpenCV 完成人脸识别还是比较有意思的,目前图像处理和人脸识别还是比较常用到的,本文主要记录学习过程,以及遇到的相关报错问题进行记录
    • 如何对于特定目标的检测并显示出结果?如何优化让人脸识别的更精准?目前还在朝着这个方向进行思考和探究

    参考:
    ubuntu16.04下ROS操作系统学习笔记(六 )机器视觉-摄像头标定-ROS+OpenCv-人脸识别-物体跟踪-二维码识别_小小何先生的博客-CSDN博客

    ROS+OpenCV 人脸识别,物体识别_JJH的创世纪的博客-CSDN博客_ros图像识别

    《ROS机器人开发实践》功能包编译报错问题解决&&摄像头数据opencv_melodic18的博客-CSDN博客

    Ubuntu 16.04 安装摄像头驱动usb_cam - 走看看

    E: 无法定位软件包 ros-kinetic-usb-cam_>>>111的博客-CSDN博客

    以上就是本文的全部内容啦!如果对您有帮助,麻烦点赞啦!收藏啦!欢迎各位评论区留言!!!

  • 相关阅读:
    操作系统实验二 进程管理
    周赛368 合法分组的最少组数(灵神笔记)
    sqlserver的字符集配置
    Spatio-temporal Self-Supervised Representation Learning for 3D Point Clouds
    Tiktok 网络、网络
    直播速递 | Plan Stitch:一种使用缝合物理计划解决查询计划性能退化问题的方法
    AWS考试认证学习
    语音识别接口试用
    C++STL学习笔记-map的属性(大小以及是否存在)
    axios 封装
  • 原文地址:https://blog.csdn.net/m0_61745661/article/details/125578352