【Linux學習】OpenCV+ROS 實現人臉識別(Ubantu16.04)
映象下載、域名解析、時間同步 阿里雲開源映象站
前言
本文主要學習 ROS機器人作業系統 ,在ROS系統裡呼叫 OpenCV庫 實現人臉識別任務
一、環境配置
1.安裝ROS
sudo apt-get install ros-kinetic-desktop-full
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.建立工作空間
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace
- 建立完成工作空間後,在根目錄下面,執行編譯整個工作空間
cd ~/catkin_ws/ catkin_make
-
工作空間中會自動生成兩個資料夾:devel,build
-
devel資料夾中產生幾個setup.*sh形成的環境變數設定指令碼,使用source命令執行這些指令碼檔案,則工作空間中的環境變數得以生效
source devel/setup.sh
- 將環境變數設定到/.bashrc檔案中
gedit ~/.bashrc
- 在開啟的檔案,最下面貼上以下程式碼即可設定環境變數
source ~/catkin_ws/devel/setup.bash
2.建立功能包
開始建立
cd ~/catkin_ws/src catkin_create_pkg learning std_msgs rospy roscpp
回到根目錄,編譯並設定環境變數
cd ~/catkin_ws catkin_make source ~/catkin_ws/devel/setup.sh
三、人臉識別檢測相關程式碼
基於 Haar 特徵的級聯分類器檢測演算法
核心內容,如下所示:
- 灰階色彩轉換
- 縮小攝像頭影像
- 直方圖均衡化
- 檢測人臉
1.python檔案
face_detector.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy import cv2 import numpy as np from sensor_msgs.msg import Image, RegionOfInterest from cv_bridge import CvBridge, CvBridgeError class faceDetector: def __init__(self): rospy.on_shutdown(self.cleanup); # 建立cv_bridge self.bridge = CvBridge() self.image_pub = rospy.Publisher("cv_bridge_image", Image, queue_size=1) # 獲取haar特徵的級聯表的XML檔案,檔案路徑在launch中傳入 cascade_1 = rospy.get_param("~cascade_1", "") cascade_2 = rospy.get_param("~cascade_2", "") # 使用級聯表初始化haar特徵檢測器 self.cascade_1 = cv2.CascadeClassifier(cascade_1) self.cascade_2 = cv2.CascadeClassifier(cascade_2) # 設定級聯表的引數,最佳化人臉識別,可以在launch中重新配置 self.haar_scaleFactor = rospy.get_param("~haar_scaleFactor", 1.2) self.haar_minNeighbors = rospy.get_param("~haar_minNeighbors", 2) self.haar_minSize = rospy.get_param("~haar_minSize", 40) self.haar_maxSize = rospy.get_param("~haar_maxSize", 60) self.color = (50, 255, 50) # 初始化訂閱rgb格式影像資料的訂閱者,此處影像topic的話題名可以在launch中重對映 self.image_sub = rospy.Subscriber("input_rgb_image", Image, self.image_callback, queue_size=1) def image_callback(self, data): # 使用cv_bridge將ROS的影像資料轉換成OpenCV的影像格式 try: cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8") frame = np.array(cv_image, dtype=np.uint8) except CvBridgeError, e: print e # 建立灰度影像 grey_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 建立平衡直方圖,減少光線影響 grey_image = cv2.equalizeHist(grey_image) # 嘗試檢測人臉 faces_result = self.detect_face(grey_image) # 在opencv的視窗中框出所有人臉區域 if len(faces_result)>0: for face in faces_result: x, y, w, h = face cv2.rectangle(cv_image, (x, y), (x+w, y+h), self.color, 2) # 將識別後的影像轉換成ROS訊息併發布 self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8")) def detect_face(self, input_image): # 首先匹配正面人臉的模型 if self.cascade_1: faces = self.cascade_1.detectMultiScale(input_image, self.haar_scaleFactor, self.haar_minNeighbors, cv2.CASCADE_SCALE_IMAGE, (self.haar_minSize, self.haar_maxSize)) # 如果正面人臉匹配失敗,那麼就嘗試匹配側面人臉的模型 if len(faces) == 0 and self.cascade_2: faces = self.cascade_2.detectMultiScale(input_image, self.haar_scaleFactor, self.haar_minNeighbors, cv2.CASCADE_SCALE_IMAGE, (self.haar_minSize, self.haar_maxSize)) return faces def cleanup(self): print "Shutting down vision node." cv2.destroyAllWindows() if __name__ == '__main__': try: # 初始化ros節點 rospy.init_node("face_detector") faceDetector() rospy.loginfo("Face detector is started..") rospy.loginfo("Please subscribe the ROS image.") rospy.spin() except KeyboardInterrupt: print "Shutting down face detector node." cv2.destroyAllWindows()
2.lanuch
usb_cam.launch
- 攝像頭啟動檔案
<launch> <node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" > <param name="video_device" value="/dev/video0" /> <param name="image_width" value="640" /> <param name="image_height" value="480" /> <param name="pixel_format" value="yuyv" /> <param name="camera_frame_id" value="usb_cam" /> <param name="io_method" value="mmap"/> </node> </launch>
face_detector.launch
- 人臉識別啟動檔案
<launch> <node pkg="test2" name="face_detector" type="face_detector.py" output="screen"> <remap from="input_rgb_image" to="/usb_cam/image_raw" /> <rosparam> haar_scaleFactor: 1.2 haar_minNeighbors: 2 haar_minSize: 40 haar_maxSize: 60 </rosparam> <param name="cascade_1" value="$(find robot_vision)/data/haar_detectors/haarcascade_frontalface_alt.xml" /> <param name="cascade_2" value="$(find robot_vision)/data/haar_detectors/haarcascade_profileface.xml" /> </node> </launch>
3.CvBridge
- ROS 與 OpenCV 之間的資料連線是透過 CvBridge 來實現的
- ROS Image Message與 OpenCV Ipllmage 之間連線的一個橋樑
cv_bridge_test.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy import cv2 from cv_bridge import CvBridge, CvBridgeError from sensor_msgs.msg import Image class image_converter: def __init__(self): # 建立cv_bridge,宣告影像的釋出者和訂閱者 self.image_pub = rospy.Publisher("cv_bridge_image", Image, queue_size=1) self.bridge = CvBridge() self.image_sub = rospy.Subscriber("/usb_cam/image_raw", Image, self.callback) def callback(self,data): # 使用cv_bridge將ROS的影像資料轉換成OpenCV的影像格式 try: cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8") except CvBridgeError as e: print e # 在opencv的顯示視窗中繪製一個圓,作為標記 (rows,cols,channels) = cv_image.shape if cols > 60 and rows > 60 : cv2.circle(cv_image, (60, 60), 30, (0,0,255), -1) # 顯示Opencv格式的影像 cv2.imshow("Image window", cv_image) cv2.waitKey(3) # 再將opencv格式額資料轉換成ros image格式的資料釋出 try: self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8")) except CvBridgeError as e: print e if __name__ == '__main__': try: # 初始化ros節點 rospy.init_node("cv_bridge_test") rospy.loginfo("Starting cv_bridge_test node") image_converter() rospy.spin() except KeyboardInterrupt: print "Shutting down cv_bridge_test node." 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
$ cd ~/catkin_ws
$ catkin_make
成功解決:
報錯2:啟動攝像頭報錯
解 決方法:輸入以下命令列,再啟動攝像頭
source ~/catkin_ws/devel/setup.bash
成功解決:
報錯3:虛擬機器攝像頭沒連線報錯
解決方法:開啟虛擬機器設定,更改usb版本為3.1
可移動裝置將攝像頭設定連線
六、總結
-
在ROS作業系統中呼叫 OpenCV 完成人臉識別還是比較有意思的,目前影像處理和人臉識別還是比較常用到的,本文主要記錄學習過程,以及遇到的相關報錯問題進行記錄
-
如何對於特定目標的檢測並顯示出結果?如何最佳化讓人臉識別的更精準?目前還在朝著這個方向進行思考和探究
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70003733/viewspace-2904820/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【ROS】OpenCV+ROS 實現人臉識別(Ubantu16.04)ROSOpenCV
- matlab實現人臉識別(數學基礎原理)Matlab
- 機器學習實戰-SVM模型實現人臉識別機器學習模型
- 純前端實現人臉識別-提取-合成前端
- 人臉識別學習筆記一:入門篇筆記
- 人臉識別學習筆記二:進階篇筆記
- 基於二哈實現多人人臉學習和識別
- [OpenCV實戰]1 基於深度學習識別人臉性別和年齡OpenCV深度學習
- 基於Android平臺實現人臉識別Android
- 如何用Excel 9步實現CNN人臉識別ExcelCNN
- 人臉識別技術,讓科幻成為現實
- 支小蜜人臉識別消費系統助力學校食堂實現“刷臉吃飯”
- opencv 人臉識別OpenCV
- OpenCV — 人臉識別OpenCV
- 如何理解並實現一個簡單的人臉識別演算法(下):人臉識別演算法
- 手把手教你運用深度學習構建影片人臉識別模型(Python實現)深度學習模型Python
- 手把手教你實現人臉識別,有手就行
- 64行程式碼實現簡單人臉識別行程
- 人臉識別技術,將電影變成現實
- 手把手教你運用深度學習構建視訊人臉識別模型(Python實現)深度學習模型Python
- 基於深度學習的人臉識別系統系列(Caffe+OpenCV+Dlib)——【六】設計人臉識別的識別類深度學習OpenCV
- 人臉檢測識別,人臉檢測,人臉識別,離線檢測,C#原始碼C#原始碼
- 【opencv3】 svm實現手寫體與人臉識別OpenCV
- 虹軟人臉識別ArcSoft3.0NodeJs 版本實現NodeJS
- Mars演算法實踐——人臉識別演算法
- 人臉識別檢測專案實戰
- 利用OpenCV和深度學習來實現人類活動識別OpenCV深度學習
- C#人臉識別入門篇-STEP BY STEP人臉識別--入門篇C#
- 智慧人臉識別門禁系統開發,人臉識別開鎖流程
- 人臉識別之特徵臉方法(Eigenface)特徵
- 前端人臉識別--兩張臉相似度前端
- 妙招:使用Python實現圖片在人臉識別並顯示Python
- Python實現人臉識別功能,face_recognition的使用 | 機器學習Python機器學習
- 手把手教你用 1 行命令實現人臉識別
- 機器學習-無監督學習(人臉識別,使用NMF進行特徵提取)機器學習特徵
- 人臉活體檢測人臉識別:眨眼+張口
- 學校人臉識別應用6大核心特性
- 乾貨 | AI人臉識別之人臉搜尋AI