This article works in the following environment.
item | value |
---|---|
CPU | Core i5-8250U |
Ubuntu | 16.04 |
ROS | Kinetic |
python | 2.7.12 |
mongodb | 2.6.10 |
For installation, refer to ROS Course 02 Installation. Also, the program in this article has been uploaded to github. See ROS Course 11 git repository.
So far, various data have been displayed on the browser, but it is troublesome to display the image acquired by ROS on the browser. Even if you save it as a ROS image, it cannot be displayed in the browser. You can export the image to a file with ROS once and view it in a browser, but I don't really want to use the file system with ROS. Here, the image data is encoded in Base64 and displayed in the browser. Also, by saving this data with mongodb, you can save the information even if the power is turned off. The base64 format is a textual representation of binary data. Converts a 3-byte binary to 4 ASCII characters.
Receive rosservice and save Image in mongodb. Delete the database. Send data to the browser.
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.b64 encode (cv2.imencode (".jpg ", frame, encode_param))
and convert it to base64 format.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>
Run
mkdir ~/.ros/mongo
roslaunch web_lecture mongo_image.launch
Embed image in html with base64 Convert to base64 with python