ROS講座56 Webカメラの画像を表示する

# 環境
この記事は以下の環境で動いています。

| 項目 | 値 |
|:-:|:-:|
| CPU | Core i5-8250U |
| Ubuntu | 20.04 |
| ROS | Noetic |
| Webカメラ | BSW200MBK(baffalo) |

インストールについては[ROS講座02 インストール](https://qiita.com/srs/items/e0e0a9dc3f94c2d3348e)を参照してください。
またこの記事のプログラムはgithubにアップロードされています。[ROS講座11 gitリポジトリ](https://qiita.com/srs/items/25a56a6abda41dcf396e)を参照してください。

# 概要
主なロボットのセンサーとしてビジョンカメラが挙げられます。専用のカメラを使うこともありますが、ROSではWebカメラを使うことが一般的です。基本的な開発としてWebカメラの画像を取得して画面に写すということをします。

# 要素の解説

## USBカメラ
uvcというクラスに対応していれば使えます。最近のWebカメラならほとんどが対応しています。
ちなみに私は[BUFFALO 200万画素WEBカメラ 広角120°マイク内蔵 ブラック BSW200MBK](https://www.amazon.co.jp/dp/B01LXYHF71/ref=asc_df_B01LXYHF712560862/?tag=jpgo-22&creative=9303&creativeASIN=B01LXYHF71&linkCode=df0&hvadid=265911612160&hvpos=1o1&hvnetw=g&hvrand=8262210518442997228&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009307&hvtargid=pla-505562245157&th=1&psc=1)というものをよく使っています。広角で使いやすいカメラです。
(現在ディスコンですが、後継機が出ています)

このカメラの使用可能なフォーマットを見てみましょう。Webカメラはどれでも同じように見えますが、使用できるフォーマット・解像度(横x縦)・レートが限られます。WebカメラをPCにつないで以下のコマンドをたたくと使用可能な組み合わせが出てきます。

```shell:Webカメラの使用可能な設定の取得
v4l2-ctl --list-formats-ext
```

```text:結果(BSW200MBKの場合)
ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'YUYV' (YUYV 4:2:2)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
##### 略 #####
	[1]: 'MJPG' (Motion-JPEG, compressed)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
##### 略 #####
```

## usb_camera
まずWebカメラとROSをつなぐドライバーが必要です。uvc_cameraとusb_camが主流でしたが、現在後者のみがnoetic対応をしているのでそちらを使いましょう
usb_camはwebカメラの画像を取得してimage形でROSトピックをpublishします。

```shell:sensor_msgs/Image型
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
uint32 height
uint32 width
string encoding
uint8 is_bigendian
uint32 step
uint8[] data
```

以下のコマンドでインストールします。

```shell
sudo apt install ros-noetic-usb-cam
```


## image_view
image_viewはimage形のROSトピックできた画像を表示します。

## Rviz
Rvizには様々なトピックを可視化する機能があります。Image型ももちろん表示することができます。


# image_viewで表示する。

## launchファイル
```xml:hard_lecture/launch/usb_cam.launch
<?xml version="1.0"?>
<launch>
  <arg name="view" default="false"/>

  <node name="head_camera" pkg="usb_cam" type="usb_cam_node">
    <param name="pixel_format" value="yuyv" />
    <param name="image_width" value="640" />
    <param name="image_height" value="480" />
  </node>
  <group if="$(arg view)">
    <node name="image_view" pkg="image_view" type="image_view" >
      <remap from="image" to="/head_camera/image_raw"/>
    </node>
  </group>
</launch>
```

* pixel_format/image_width/image_heightで先ほどWebカメラで使えると調べたものを選択します。ただしformatはmjpeg、yuyv、uyvyの3つしか選択できないみたいです。 

# 実行

```shell:
roslaunch cam_lecture cam_view.launch view:=true
```

以下のようなウィンドウが現れます。
![cam_simple1.png](https://qiita-image-store.s3.amazonaws.com/0/254442/1a02bd82-b787-406a-de5c-675f47b71f9b.png)

# Rvizで表示する。

## launchファイル
```xml:cam_lecture/launch/cam_rviz.launch
<?xml version="1.0"?>
<launch>
  <arg name="rvizconfig" default="$(find cam_lecture)/rviz/cam_rviz.rviz" />
  <node name="uvc_camera_node" pkg="uvc_camera" type="uvc_camera_node" />
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />
</launch>
```

## 実行
各ターミナルごとに実行前にsource ~/catkin_ws/devel/setup.bashを実行する必要があります。

```shell
roslaunch cam_lecture cam_rviz.launch 
```

![cam_simple2.png](https://qiita-image-store.s3.amazonaws.com/0/254442/92eeeab4-b860-d677-7338-eba81ecb1067.png)

この状態で「$rostopic list」をすると以下のようなリストが現れます。`/head_camera/image_raw`が非圧縮の画像のトピックです。

```text
/image_view/output
/image_view/parameter_descriptions
/image_view/parameter_updates
/rosout
/rosout_agg
/head_camera/camera_info
/head_camera/image_raw
/head_camera/image_raw/compressed
/head_camera/image_raw/compressed/parameter_descriptions
/head_camera/image_raw/compressed/parameter_updates
/head_camera/image_raw/compressedDepth
/head_camera/image_raw/compressedDepth/parameter_descriptions
/head_camera/image_raw/compressedDepth/parameter_updates
/head_camera/image_raw/theora
/head_camera/image_raw/theora/parameter_descriptions
/head_camera/image_raw/theora/parameter_updates

```

## rvizの設定

上記のROS launchの実行をしている間に`rziv`コマンドで立ち上げます。
「add」ボタンを押す -> Imageを選択する。DisplayウィンドウのImageの「Image Topic」でトピックの名前を選択します。
![cam_simple3.png](https://qiita-image-store.s3.amazonaws.com/0/254442/c7edb5ae-51e5-b20c-895b-b00355a4d5c3.png)

# 参考
[ROSでカメラ画像を表示](http://asukiaaa.blogspot.com/2013/05/blog-post_14.html)

# 目次ページへのリンク
[ROS講座の目次へのリンク](https://qiita.com/srs/items/5f44440afea0eb616b4a)