機器人視覺是機器人應用中至關重要的一部分,獲取機 器人的視覺圖像及進行人臉識別是很多應用的基礎。

一、 在仿真環境中獲取機器人平面視覺圖像

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節點

運行后可以看到終端程序中顯示檢測到的人臉坐標信息。終端程序人臉識別結果如圖所示。

來源: 部分來自網絡