ROS中階筆記(五):機器人感知—機器視覺
1 ROS中的圖像數據
1.1 二維圖像
1.1.1 安裝安裝usb_cam
步驟一,檢測電腦是安裝usb_cam還是應該安裝uvc_cam
$ lsusb #查看usb攝像頭
打開網址:http://www.ideasonboard.org/uvc/,查看與自己攝像頭匹配的ID號。
如果有,就說明你的筆記本攝像頭比較好,有他的廠商提供的linux驅動,是uvc_cam
沒有匹配的ID,說明是usb_cam。
Bus 001 Device 002: ID 04f2:b6d9 Chicony Electronics Co., Ltd #攝像頭
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 004: ID 0e0f:0008 VMware, Inc.
Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
步驟二,查看攝像頭設備
$ ls /dev/video* #默認筆記本自帶攝像頭是video0
步驟三,測試您的網絡攝像頭;(虛擬機+ubuntu16.04)
$ sudo apt-get install cheese
$ cheese # 啟動cheese查看攝像頭情況
步驟四,安裝usb_cam
$ sudo apt-get install ros-kinetic-usb-cam # 安裝攝像頭功能包
$ roslaunch usb_cam usb_cam-test.launch # 啟動功能包
$ rqt_image_view # 可視化工具
新版本的usb_cam包在launch文件夾下有自帶的launch文件,名叫usb_cam-test.launch
1.1.2 顯示圖像數據
顯示圖像類型
$ roslaunch usb_cam usb_cam-test.launch
$ rostopic info /usb_cam/image_raw
查看圖像消息
$ rosmsg show sensor_msgs/Image
- Header:消息頭,包含消息序號,時間戳和綁定坐標系;
- height:圖像的縱向分辨率;
- width:圖像的橫向分辨率;
- encoding:圖像的編碼格式,包含RGB、YUV等常用格式,不涉及圖像壓縮編碼;
- is_bigendian:圖像數據的大小端存儲模式;
- step:一行圖像數據的字節數量,作為數據的步長參數;
- data:存儲圖像數據的數組,大小為step*height個字節;
1080 * 720分辨率的攝像頭產生一幀圖像的數據大小是 3 * 1080 * 720=2764800字節,即2.7648MB
壓縮圖像消息
$ rosmsg show sensor_msgs/CompressedImage
- format:圖像的壓縮編碼格式(jpeg,png,bmp)
- data:存儲圖像數據數組
1.2 三維圖像(kinect)
紅外攝像頭采集三維點雲數據,采集的位置信息從xyz三個方向上描述,每一個方向上的數據都是一個浮點數;
一個浮點數占據的空間大小為4個字節。
顯示點雲類型
$ roslaunch freenet_launch freenect.launch #啟動kinect
$ rostopic info /camera/depth_registered/points
查看點雲消息
$ rosmsg show sensor_msgs/PointCloud2
- height:點雲圖像的縱向分辨率;
- width:點雲圖像的橫向分辨率;
- fields:每個點的數據類型;
- is_bigendian:數據的大小端存儲模式;
- point_step:單點的數據字節步長;
- row_step:一列數據的字節步長;
- data:點雲數據的存儲數組,總字節大小為row_step*height;
- is_dense:是否有無效點;如果有無效點,考慮這一幀的圖像數據是否保留或者舍棄。
點雲單幀數據量也很大,如果使用分布式網絡傳輸,需要考慮能否滿足數據的傳輸要求,或者針對數據進行壓縮。
2 攝像頭標定
2.1 攝像頭標定准備工作
圖像數據采集之前,需要把攝像頭進行一些標定,關於如何標定,我們需要外部工具:棋盤格標定靶
攝像頭為什么要標定?
攝像頭這種精密儀器對光學器件的要求較高,由於攝像頭內部與外部的一些原因,生成的物體圖像往往會發生畸變,為避免數據源造成的誤差,需要針對攝像頭的參數進行標定。
安裝標定功能包
$ sudo apt-get install ros-kinetic-camera-calibration
2.2 攝像頭標定流程
2.2.1 普通攝像頭標定流程
1.啟動攝像頭
$ roslaunch robot_vision usb_cam.launch # 啟動攝像頭功能包
$ roslaunch usb_cam usb_cam-test.launch # 啟動攝像頭功能包
2.啟動標定包
$ rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024 image:=/usb_cam/image_raw camera:=/usb_cam
# 8x6,中間是x,而不是乘號;
# 啟動標定包之后,把棋盤格標定靶放在攝像頭的可視范圍內;
# square 0.024 實際打印出來紙張的正方形邊長,自己拿尺子測量;0.024米
- 1.size:標定棋盤格的內部角點個數,這里使用的棋盤一共有六行,每行有8個內部角點;
- 2.square:這個參數對應每個棋盤格的邊長,單位是米;
- 3.image和camera:設置攝像頭發布的圖像話題;
3.標定過程
- X:標定靶在攝像頭視野中的左右移動,變為綠色說明已經滿足標定需求;
- Y:標定靶在攝像頭視野中的上下移動;
- Size:標定靶在攝像頭視野中的前后(遠近)移動;
- Skew:標定靶在攝像頭視野中的傾斜轉動;
CALIBRATE:標定之前是灰色;標定成功之后,變為深綠色,說明當前標定已經結束;點擊它,界面好像未響應,這是因為它在后台進行數據運算,不要關閉;
后面兩個灰色灰色按鍵SAVE、COMMIT變為深綠色,說明計算完成;
4.同時在終端中顯示標定結果:
點擊按鍵SAVE,在終端中顯示標定的數據放在哪一個路徑下面;
('Wrote calibration data to', '/tmp/calibrationdata.tar.gz')
5.解壓縮——找到標定文件
('Wrote calibration data to', '/tmp/calibrationdata.tar.gz')
找到calibrationdata.tar.gz文件,解壓,里面有很多圖片(在做標定的時候,采樣圖片,這些圖片已經沒用),我們需要只有一個文件ost.yaml
文件,把這個文件拷貝到功能包(自己建的任務的功能包)下面;
image_width: 640
image_height: 480
camera_name: narrow_stereo
camera_matrix:
rows: 3
cols: 3
data: [672.219498, 0.000000, 322.913816, 0.000000, 676.060141, 220.617820, 0.000000, 0.000000, 1.000000]
distortion_model: plumb_bob
distortion_coefficients:
rows: 1
cols: 5
data: [-0.146620, 0.187588, 0.001657, 0.000009, 0.000000]
rectification_matrix:
rows: 3
cols: 3
data: [1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000]
projection_matrix:
rows: 3
cols: 4
data: [655.937012, 0.000000, 323.001754, 0.000000, 0.000000, 665.393311, 220.554221, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000]
2.2.2 Kinect標定流程
Kinect包含彩色攝像頭和紅外攝像頭,我們需要針對兩個攝像頭分別做標定。
1.啟動Kinect
$ roslaunch robot_vision freenect.launch
2.啟動彩色攝像頭
$ rosrun camera_calibration cameracalibrator.py image:=/camera/rgb/image_raw camera:=/camera/rgb --size 8x6 --square 0.024
3.標定紅外攝像頭
$ rosrun camera_calibration cameracalibrator.py image:=/camera/ir/image_raw camera:=/camera/ir --size 8x6 --square 0.024
2.3 攝像頭使用標定文件
2.3.1 普通攝像頭如何使用標定文件?
在launch文件中加載標定文件,通過camera_info_url參數來進行加載;
2.3.2 Kinect如何使用標定文件?
Kinect因為有兩個標定文件,因此需要通過兩個參數的加載來完成;把兩個文件都加載在進來。
2.3.3 使用標定文件時可能產生的錯誤
原因:標定文件中camera_name參數與實際傳感器名稱不匹配
解決方法:按照警告提示的信息進行修改即可。
比如根據上圖所示的警告,分別將兩個標定文件.yaml
中的camera_name參數修改為
“rgb_A70774707163327A”、“depth_A70774707163327A”即可。
3 ROS+OpenCV
3.1 OpenCV簡介
Open Source Computer Vision Library;基於BSD許可發行的跨平台開源計算機視覺庫(Linux、Windows和Mac OS等);由一系列C函數和少量C++類構成,同時提供C++、Python、Ruby、MATLAB等語言的接口;實現了圖像處理和計算機視覺方面的很多通用算法,而且對非商業應用和商業應用都是免費的;可以直接訪問硬件攝像頭,並且還提供了一個簡單的GUl系統一highgui。
3.2 OpenCV使用
安裝OpenCV
$ sudo apt-get install ros-kinetic-vision-opencv libopencv-dev python-opencv
測試例程
$ roslaunch robot_vision usb_cam.launch # 啟動攝像頭
$ rosrun robot_vision cv_bridge_test.py # 打開opencv圖像,自己的api接口
$ rqt_image_view # ROS中的圖像
imgmsg_to_cv2():將ROS圖像消息轉換成OpenCV圖像數據
cv2_to_imgmsg():將OpenCV格式的圖像數據轉換成ROS圖像消息
輸入參數:
1.圖像消息流
2.轉換的圖像數據格式
3.3 人臉識別
啟動人臉識別實例
$ roslaunch robot_vision usb_cam.launch # 啟動攝像頭
$ roslaunch robot_vision face_detector.launch # 啟動人臉識別功能節點
$ rqt_image_view
初始化部分:完成ROS節點、圖像、識別參數的設置。
ROS圖像回調函數:將圖像轉化成OpenCV的數據格式,然后預處理之后開始調用人臉識別的功能函數,最后把識別的結果發布。
人臉識別:調用OpenCV提供的人臉識別接口,與數據庫中的人臉特征進行匹配。
3.4 物體跟蹤
啟動物體跟蹤實例
$ roslaunch robot_vision usb_cam.launch # 啟動攝像頭
$ roslaunch robot_vision motion_detector.launch # 啟動物體跟蹤功能節點
$ rqt_image_view
初始化部分:完成ROS節點、圖像、識別參數的設置
圖像處理:將圖像轉換成OpenCV格式;完成圖像預處理之后開始針對兩幀圖像進行比較,基於圖像差異識別到運動的物體,最后標識識別結果並發布
4 二維碼識別
4.1 二維碼使用
安裝二維碼識別功能包
$ sudo apt-get install ros-kinect-ar-track-alvar
創建二維碼
$ rosrun ar_track_alvar createMarker
$ rosrun ar_track_alvar createMarker 0
$ roscd robot_vision/config
$ rosrun ar_track_alvar createMarker -s 5 0 #邊長5厘米,數字為0的二維碼
$ rosrun ar_track_alvar createMarker -s 5 1
$ rosrun ar_track_alvar createMarker -s 5 2
4.2 攝像頭二維碼識別
1.啟動攝像頭二維碼識別示例
$ roslaunch robot_vision usb_cam_with_calibration.launch
$ roslaunch robot_vision ar_track_camera.launch
啟動攝像頭時,需要加載標定文件,否則可能無法識別二維碼。
2.查看識別到的二維碼位姿
$ rostopic echo /ar_pose_marker
4.3 Kinect二維碼識別
啟動Kinect二維碼識別示例
$ roslaunch robot_vision freenect.launch
$ roslaunch robot_vision ar_track_kinect.launch
5 擴展內容:物體識別與機器學習
Object Recognition Kitchen(ORK) 物體識別框架
TensorFlow Object Detection API 識別API
6 參考資料
ROS cV_bridge wiki: http://wiki.ros.org/cv_bridge
ROS opencv_apps: http://wiki.ros.org/opencv_apps