ubuntu16.04下ROS作業系統學習(七 / 二)機器視覺-人臉識別
阿新 • • 發佈:2018-12-21
基於Haar特徵的級聯分類器檢測演算法主要步驟:
- 灰階色彩轉換
- 縮小攝像頭影象
- 直方圖均衡化
- 檢測人臉
程式碼檔案以及視訊解釋等相關檔案在我github裡面都可以去找到,這裡不方便貼出來。分別在三個終端執行以下命令:
roslaunch robot_vision usb_cam.launch
roslaunch robot_vision face_detector.launch
rqt_image_view
顯示結果:
我們接下來看一下程式碼:
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()
我們首先需要初始化ros節點,之後呼叫人臉檢測器,然後打印出日誌資訊,等待回撥函式等等。
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()
我們首先初始化一些引數,之後當我們接收到ros來的影象的話,我們呼叫回撥函式,將影象轉換成OpenCv的資料格式,在opencv裡面建立灰度影象,建立平衡直方圖,減少光線影響,之後檢測人臉,這些操作都是通過呼叫函式來實現的,然後將人臉用一個方框框出來。