【Linux學習】OpenCV+ROS 實現人臉識別(Ubantu16.04)

来源:https://www.cnblogs.com/helong-123/archive/2022/07/08/16457395.html
-Advertisement-
Play Games

鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 前言 本文主要學習 ROS機器人操作系統 ,在ROS系統里調用 OpenCV庫 實現人臉識別任務 一、環境配置 1.安裝ROS sudo apt-get install ros-kinetic-desktop-full 2.攝像頭調用 安裝攝像頭 ...


鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站

前言

本文主要學習 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

調用攝像頭成功,如下圖所示:

file

攝像頭的驅動發佈的相關數據,如下圖所示:

file

攝像頭 usb_cam/image_raw 這個話題,發佈的消息的具體類型,如下圖所示:

file

那麼圖像消息裡面的成員變數有哪些呢?

列印一下就知道了!一個消息類型裡面的具體成員變數,如下圖所示:

file

  • Header:很多話題消息裡面都包含的

    消息頭:包含消息序號,時間戳和綁定坐標系

    消息的序號:表示我們這個消息發佈是排第幾位的,並不需要我們手動去標定,每次

    發佈消息的時候會自動地去累加

    綁定坐標系:表示的是我們是針對哪一個坐標系去發佈的header有時候也不需要去配置

  • height:圖像的縱向解析度

  • width:圖像的橫向解析度

  • encoding:圖像的編碼格式,包含RGB、YUV等常用格式,都是原始圖像的編碼格式,不涉及圖像壓縮編碼

  • is_bigendian: 圖像數據的大小端存儲模式

  • step:一行圖像數據的位元組數量,作為數據的步長參數

  • data:存儲圖像數據的數組,大小為step×height個位元組

  • format:圖像的壓縮編碼格式(jpeg、png、bmp)

3.導入OpenCV

file

在ROS當中完成OpenCV的安裝,命令行如下圖所示:

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

安裝完成

file

二、創建工作空間和功能包

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站官方送的書來進行測試,識別的效果還是相當不錯的,效果如下圖所示:

file

五、報錯解決

報錯1:E:無法定位軟體包 ros-kinetic-usb-cam

file

解決方法: 網上下載編譯安裝

$ cd catkin_ws/src

$ git clone https://github.com/bosch-ros-pkg/usb_cam.git

$ cd ~/catkin_ws

$ catkin_make

成功解決:

file

報錯2:啟動攝像頭報錯

file

file決方法:輸入以下命令行,再啟動攝像頭

source ~/catkin_ws/devel/setup.bash

成功解決:

file

報錯3:虛擬機攝像頭沒連接報錯

file

解決方法:打開虛擬機設置,更改usb版本為3.1

file

可移動設備將攝像頭設置連接

file

六、總結

  • 在ROS操作系統中調用 OpenCV 完成人臉識別還是比較有意思的,目前圖像處理和人臉識別還是比較常用到的,本文主要記錄學習過程,以及遇到的相關報錯問題進行記錄

  • 如何對於特定目標的檢測並顯示出結果?如何優化讓人臉識別的更精準?目前還在朝著這個方向進行思考和探究

原文鏈接:https://blog.csdn.net/m0_61745661/article/details/125578352


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .Net下極限生產力之分表分庫全自動化Migrations Code-First ## 介紹 本文ShardinfCore版本x.6.x.x+ 本期主角: - [`ShardingCore`](https://github.com/dotnetcore/sharding-core) 一款ef-cor ...
  • VMware15.5虛擬機安裝CentOS7.5詳細教程 (前言)軟體下載 需要VMware15.5軟體和密匙的小伙伴可以從此地址下載:https://pan.baidu.com/s/1A8HaMXtCXAULeol8Ifuiaw 提取碼:zb3b。 需要CentOS7.5鏡像的小伙伴可以從此地址下 ...
  • 全世界口碑最好的塔防系列游戲榮耀回歸——Kingdom Rush Vengeance中文版,游戲率領黑暗大軍步步緊逼,讓整個王國為你而顫抖吧!你將直面凶猛殘暴的強敵,與至高至強的 boss 們展開終極決戰。將防禦塔與武器自由搭配,實現最具殺傷力的組合。 詳情:王國保衛戰:復仇Kingdom Rush ...
  • Internet層 Internet層相關協議 ICMP協議: Internet Control Message Protocol,用於探測網路中的狀態,ping命令使用的就是icmp協議(向網路中發送icmp協議數據包,根據網路的狀態返回不同的提示信息),不但能檢測網路的狀態,還能檢測網路的速度。 ...
  • 目錄 一、前景回顧 二、線程的實現 三、線程的切換 四、運行測試 一、前景回顧 上一回我們實現了記憶體管理系統,說實話代碼還是比較多,看起來還是比較頭疼的,不過為了知識這都是小事。這一節終於可以來實現我們的線程了,以前學操作系統的時候,聽到的最多的就是什麼線程,進程等,這一回我們來自己動手實現一下,加 ...
  • WaveLab 11 Pro是一款非常強大的母帶製作工具,引入了對多通道交錯文件的擴展支持,並且首次在音頻編輯器中引入了多通道交錯編輯。WaveLab 11 Pro Mac版支持多達 22.2 環繞聲佈局的 WAV 文件(包括用於預創作目的的 Ambisonics 文件),可以像任何其他單聲道/立體 ...
  • Transmit 5是專為mac用戶設計的一款功能強大的ftp客戶端,Transmit Mac版同步功能增加了對本地到本地和遠程到遠程同步的支持,同時還為您提供了更精細的控制。與此同時,用戶還可以通過Transmit在任意應用程式中無須下載即可實時編輯文檔,除此之外,用戶還可以通過Transmit的 ...
  • DaVinci Resolve Studio 18 for Mac是一款Mac的達芬奇調色軟體,DaVinci Resolve 18是一次重大更新,這一版本彙集了超過100項新功能和200項改進!調色頁面設立了新的HDR調色工具,重新設計了一級校色控制工具,並添加了基於AI的Magic Mask遮罩 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...