5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ROS講座114 DataBaseで画像を扱いブラウザからアクセスする

Last updated at Posted at 2020-04-15

環境

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

項目
CPU Core i5-8250U
Ubuntu 16.04
ROS Kinetic
python 2.7.12
mongodb 2.6.10

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

概要

これまでいろいろなデータをブラウザで表示しましたが、ROSで取得した画像をブラウザで表示するのは面倒です。
ROSのimage形で保存してもブラウザでは表示できません。一度ROSで画像をファイルに書き出してブラウザで見ることもできますが、あまりROSでファイルシステムを使いたくありません。
ここでは画像のデータをBase64でエンコードすることでブラウザで表示を行います。またmongodbでこのデータを保存することで、電源を切っても情報を保存しておけます。
base64形式はバイナリーデータをテキストで表すものです。3バイトのバイナリーを4つのASCII文字に変換します。

ソースコード

rosserviceを受けてImageをmongodbに保存する。データベースの削除をする。browserに対してデータを送信します。

mongodbにアクセスするROSノード

web_lecture/scripts/mongo_image.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy
from std_srvs.srv import Empty, EmptyResponse
from sensor_msgs.msg import Image
from web_lecture.msg import StringStamp
from web_lecture.srv import StringStampList, StringStampListResponse
from mongodb_store.message_store import MessageStoreProxy
from cv_bridge import CvBridge, CvBridgeError
import base64
import cv2

class MongoImage:
    def __init__(self):
        rospy.Service('shot', Empty, self.shotCallback)
        rospy.Service('delete', Empty, self.deleteCallback)
        rospy.Service('request', StringStampList, self.requestCallback)
        rospy.Subscriber("/image_raw", Image, self.imageCallback)
        self.last_image = Image()
        self.scale = 0.5
        self.bridge = CvBridge()
        self.last_base64 = None
        self.msg_store = MessageStoreProxy(database="srs", collection="image_stamp")

    def imageCallback(self, msg):
        self.last_image = msg

    def shotCallback(self, msg):
        frame = self.bridge.imgmsg_to_cv2(self.last_image, "bgr8")
        height = frame.shape[0]
        width = frame.shape[1]
        frame2 = cv2.resize(frame , (int(width*self.scale), int(height*self.scale)))
        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 50]
        result, frame3 = cv2.imencode(".jpg", frame2, encode_param)
        mongo_data = StringStamp()
        mongo_data.stamp = rospy.get_rostime()
        mongo_data.data = base64.b64encode(frame3)
        try:
            p_id = self.msg_store.insert(mongo_data)            
        except rospy.ServiceException, e:
            print "Service call failed: %s"%e
        return EmptyResponse()

    def deleteCallback(self, msg):
        list = self.msg_store.query(StringStamp._type)
        for item in list:
            self.msg_store.delete(str(item[1]["_id"]))
        return EmptyResponse()

    def requestCallback(self, msg):
        mongo_list = self.msg_store.query(StringStamp._type)
        output = []
        try:
            for item in mongo_list:
                output.append(item[0])
        except rospy.ServiceException, e:
            print "Service call failed: %s"%e  
        return StringStampListResponse(output)

if __name__ == '__main__':
    rospy.init_node('mongo_image')
    mongo_image = MongoImage()
    rospy.spin()
  • base64.b64encode(cv2.imencode(".jpg", frame, encode_param))でopencv形式からjpg形式のデータを作り、それをbase64形式に変換します。
  • mongodbでは一括で削除をするというapiはありません。一度queryで一覧を取得してからdeleteを行います。

blowserで表示するhtml

web_lecture/www/image_view.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    web_lecture index.html
  </head>
  <body>
    <p>
      <a href="pub.html">pub.html</a> <br/>
      <a href="sub.html">sub.html</a> <br/>
      <a href="camera.html">camera.html</a> <br/>
      <a href="camera_full.html">camera_full.html</a> <br/>
      <a href="twist.html">twist.html</a> <br/>
      <a href="gamepad_api_test.html">gamepad_api_test.html</a> <br/>
      <a href="gamepad.html">gamepad.html</a> <br/>
      <a href="image_view.html">image_view.html</a> <br/>
    </p>
  </body>
</html>

実行

実行
mkdir ~/.ros/mongo
roslaunch web_lecture mongo_image.launch 

mongo_image.gif

  • 「shot」を押すとカメラに写っている画像を保存します。
  • 「request」を押すと保存されている画像をblowserに表示します。
  • 「delete」を押すと保存されている画像をすべて消去します。

参考

base64で画像をhtmlに埋め込む
pythonでbase64に変換

目次ページへのリンク

ROS講座の目次へのリンク

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?