ROS講座62 Webカメラの画像をブラウザから見る


環境

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

項目
CPU Core i5-8250U
Ubuntu 20.04
ROS Noetic

インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。

概要

例えばロボットのカメラの画像を遠隔から監視してロボットを動かしたいという場合があります。手元にubuntuやROSの載っているPCがあればよいのですが、タブレットやスマホから見たいとするとweb経由でカメラを見るのが便利です。

web video server

web video serverはrosの中のimage形のトピックをwebに配信してくれるノードです。便利なことに、特にTopic名を指定しなくても自動でImage型のTopicを探して配信してくれます。
paramで変えられますが、デフォルトでは8080ポートで動作します。

インストール
sudo apt-get install -y ros-noetic-web-video-server

ソースコード

laucnch

wwwサーバーノード、カメラノードとImageの配信ノードの3つを立ち上げます。

web_lecture/launch/camera_stream.launch
<launch>
  <include file="$(find hard_lecture)/launch/usb_cam.launch" />

  <include file="$(find roswww)/launch/roswww.launch" />
  <node pkg="web_video_server" type="web_video_server" name="web_video_server" />
</launch>

htmlファイル

カメラ画像を見るためのhtmlファイルです。

web_lecture/www/camera.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  <head>
    <title>ROS Image Web Viewer</title>
  </head>

  <body>
    <h1>/image_raw</h1>
    <script>
      document.write("<img src='http://"+location.hostname +":8080/stream?topic=/image_raw&type=ros_compressed'></img>");
    </script>
 </body>
</html>

実行

USBカメラをPCに刺します。ls /dev/video0があることを確認して、以下のコマンドでwebサーバー達を起動します。

roslaunch web_lecture camera_stream.launch 

web_video_serverが生成するページから見る

この状態でブラウザを開いてlocalhost:8080にアクセスします。すると以下のようなページが出てきます。Image型でpublishされているTopicの一覧が出てくるので、目的のTopicをクリックします。

クリックすると以下のようなページになって、動画のストリームが見れます。

http://localhost:8080/stream?topic=/image_raw/image_rawに流れている画像が見れます。
http://localhost:8080/stream?topic=/image_raw&type=ros_compressedだとcompressedで圧縮されている画像が見れます。

roswwwのページから見る

今までと同じようにhttp://localhost:8085のサーバーから見る方法を考えます。
http://localhost:8086/web_lecture/camera.htmlにアクセスをします。このページでは8086のサーバーのhtmlから8080のサーバーの画像を取得するために少しjavascriptで小細工をしています。

web_lecture/www/camera.htmlの一部
<script>
      document.write("<img src='http://"+location.hostname +":8080/stream?topic=/head_camera/image_raw&type=ros_compressed'></img>");
</script>

全画面で見る

スマホ等の画面にフルスクリーンのようにできる限り大きく映したいことがあります。

<!doctype html>
<html lang="ja">
  <head>
    <title>ROS Image Web Viewer</title>  
    <style>
    *{
      margin: 0px;
      padding: 0px;
      border: 0px;
    }
    .full_picture{
      width: 100vw;
      height: 100vh;
      object-fit: contain;
    }
    </style>
  </head>

  <body>
    <script>
      var image_topic = "/head_camera/image_raw";
      document.write("<img class='full_picture' src='http://"+location.hostname +":8080/stream?topic=" + image_topic + "&type=ros_compressed'></img>");
    </script>
  </body>
</html>

これで/head_camera/image_rawのトピックがフルスクリーンで表示されます。
<style>要素内はCSSの記述です。 *{margin: 0px; padding: 0px; border: 0px;}は全ての要素について余白を無く表示するための指定です。これがないと余計な余白が表示されます。

上記のようにlocation変数を使うことでうまく画像のurlを生成しています。 .full_picture{width: 100vw; height: 100vh; object-fit: contain;}がフルスクリーン表示をしているところです。vwvhはブラウザのサイズに対する大きさの指定で、ブラウザの画面と同じ大きさを指定しています。object-fit: containは元の画像のアスペク比を保ったまま画像が収まるようにできる限り拡大するという指定です。

参考

web video server
javascript: locationについて

目次ページへのリンク

ROS講座の目次へのリンク