ROS+OpenCV 人脸识别,物体识别

比眉伴天荒 2023-02-17 11:03 92阅读 0赞

目录

人脸识别

1.环境准备

2.创建工作空间与功能包

3.人脸识别程序

4.launch文件

5.执行

物体追踪


人脸识别

1.环境准备

首先准备ROS系统,基于ros的软件支持opencv,usbcam

apt install ros-kinetic-desktop-full

apt install ros-kinetic-opencv3

apt install ros-kinetic-usb-cam

2.创建工作空间与功能包

在创建功能包时导入依赖库

  1. $ source /opt/ros/kinetic/setup.zsh
  2. $ mkdir -p ~/catkin_ws/src
  3. $ cd ~/catkin_ws/src
  4. $ catkin_init_workspace
  5. $ cd ~/catkin_ws
  6. $ catkin_make
  7. $ souce ~/catkiin_ws/devel/setup.zsh
  8. $ cd ~/catkin_ws/src
  9. $ catkin_create_pkg test1 rospy roscpp std_msgs sensor_msgs cv_bridge image_transport
  10. $ cd ~/catkin_ws
  11. $ catkin_make
  12. $ source devel/setup.zsh

创建文件目录结构

scripts存放代码,launch存放启动文件

  1. $cd test2
  2. $mkdir launch scripts

3.人脸识别程序

$cd test2/scripts

$touch 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()

4.launch文件

$cd test2/launch

$touch usb_cam.launch face_detector.launch

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>

5.执行

分别开启三个终端,执行以下命令

$roslaunch test2 usb_cam.launch

$roslaunch test2 face_detector.launch

$rqt_image_view //也可用rviz订阅

正面效果

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NrNzg0MTAxNzc3_size_16_color_FFFFFF_t_70

侧面效果

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NrNzg0MTAxNzc3_size_16_color_FFFFFF_t_70 1

物体追踪

程序如下,使用方式同人脸识别,在scripts目录放入程序,在launch目录放入launch文件

  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 motionDetector:
  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. # 设置参数:最小区域、阈值
  15. self.minArea = rospy.get_param("~minArea", 500)
  16. self.threshold = rospy.get_param("~threshold", 25)
  17. self.firstFrame = None
  18. self.text = "Unoccupied"
  19. # 初始化订阅rgb格式图像数据的订阅者,此处图像topic的话题名可以在launch文件中重映射
  20. self.image_sub = rospy.Subscriber("input_rgb_image", Image, self.image_callback, queue_size=1)
  21. def image_callback(self, data):
  22. # 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
  23. try:
  24. cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
  25. frame = np.array(cv_image, dtype=np.uint8)
  26. except CvBridgeError, e:
  27. print e
  28. # 创建灰度图像
  29. gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  30. gray = cv2.GaussianBlur(gray, (21, 21), 0)
  31. # 使用两帧图像做比较,检测移动物体的区域
  32. if self.firstFrame is None:
  33. self.firstFrame = gray
  34. return
  35. frameDelta = cv2.absdiff(self.firstFrame, gray)
  36. thresh = cv2.threshold(frameDelta, self.threshold, 255, cv2.THRESH_BINARY)[1]
  37. thresh = cv2.dilate(thresh, None, iterations=2)
  38. binary, cnts, hierarchy= cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  39. for c in cnts:
  40. # 如果检测到的区域小于设置值,则忽略
  41. if cv2.contourArea(c) < self.minArea:
  42. continue
  43. # 在输出画面上框出识别到的物体
  44. (x, y, w, h) = cv2.boundingRect(c)
  45. cv2.rectangle(frame, (x, y), (x + w, y + h), (50, 255, 50), 2)
  46. self.text = "Occupied"
  47. # 在输出画面上打当前状态和时间戳信息
  48. cv2.putText(frame, "Status: {}".format(self.text), (10, 20),
  49. cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
  50. # 将识别后的图像转换成ROS消息并发布
  51. self.image_pub.publish(self.bridge.cv2_to_imgmsg(frame, "bgr8"))
  52. def cleanup(self):
  53. print "Shutting down vision node."
  54. cv2.destroyAllWindows()
  55. if __name__ == '__main__':
  56. try:
  57. # 初始化ros节点
  58. rospy.init_node("motion_detector")
  59. rospy.loginfo("motion_detector node is started...")
  60. rospy.loginfo("Please subscribe the ROS image.")
  61. motionDetector()
  62. rospy.spin()
  63. except KeyboardInterrupt:
  64. print "Shutting down motion detector node."
  65. cv2.destroyAllWindows()

launch

  1. <launch>
  2. <node pkg="test2" name="motion_detector" type="motion_detector.py" output="screen">
  3. <remap from="input_rgb_image" to="/usb_cam/image_raw" />
  4. <rosparam>
  5. minArea: 500
  6. threshold: 25
  7. </rosparam>
  8. </node>
  9. </launch>

执行效果

被识别出的物体有篮球,柜子,手臂,衣袖,被识别物体用边框圈出

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NrNzg0MTAxNzc3_size_16_color_FFFFFF_t_70 2

发表评论

表情:
评论列表 (有 0 条评论,92人围观)

还没有评论,来说两句吧...

相关阅读

    相关 人脸识别

    计划 实现了一个基于 PCA 的人脸识别 方法 ,我 称之为 “ 特征点方法 ”, 所有的功能简单而且实用 。 下面,我使用一个简单的MATLAB脚本 说明 它的用法

    相关 人脸识别

    人脸检测 [长文干货!走近人脸检测:从 VJ 到深度学习(上)][VJ] [长文干货!走近人脸检测:从VJ到深度学习(下)][VJ 1]

    相关 人脸识别杂谈

    Gabor 及 LBP 特征描述子是迄今为止在人脸识别领域最为成功的两种人工设计局部描述子。 对各种人脸识别影响因子的针对性处理也是那一阶段的研究热点,比如人脸光照归一化、人