次のシステムを構築するための検証です。
Grove IoT スターターキット for SORACOM で作るリモートカメラシステム
画像の受け渡しが MQTT ブローカー経由でできるか。
画像ファイルは、計測した数値データと較べて、かなり大きい。
以下のプログラムを作成しました。
jpg を JSON に変換するプログラム
JSON を publish するプログラム
subscribe で JSON を受け取るプログラム
JSON を jpg に変換するプログラム
jpg を JSON に変換するプログラム
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
# jpg_to_json.py
#
# Aug/17/2021
#
# ------------------------------------------------------------------
import sys
import os
import json
import base64
#
# ------------------------------------------------------------------
def file_write_proc(file_name,str_out):
fp_out = open(file_name,mode='w',encoding='utf-8')
fp_out.write(str_out)
fp_out.close()
#
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
name_base = sys.argv[1]
file_jpg = name_base + ".jpg"
file_json = name_base + ".json"
sys.stderr.write(file_jpg + "\n")
sys.stderr.write(file_json + "\n")
file_data = open(file_jpg, "rb").read()
b64_data = base64.b64encode(file_data).decode('utf-8')
sys.stderr.write("len(b64_data) = %d\n" % len(b64_data))
#
unit_aa = {}
unit_aa['base64'] = b64_data
unit_aa['filename'] = file_jpg
#
out_str = json.dumps(unit_aa)
file_write_proc(file_json,out_str)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
JSON を publish するプログラム
#! /usr/bin/python3
#
# publish.py
#
# Aug/17/2021
# ------------------------------------------------------------------
import sys
import paho.mqtt.client as mqtt
MQTT_HOST = "violet.local"
MQTT_TOPIC = "sample/imageTopic"
MQTT_PORT = 1883
MQTT_KEEP_ALIVE = 60
# ------------------------------------------------------------------
def on_connect(mqttc, obj, flags, rc):
print("rc: " + str(rc))
# ------------------------------------------------------------------
def file_to_str_proc(file_in):
str_out = ""
try:
fp_in = open(file_in,encoding='utf-8')
str_out = fp_in.read()
fp_in.close()
except Exception as ee:
sys.stderr.write("*** error *** file_to_str_proc ***\n")
sys.stderr.write(str (ee))
#
return str_out
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_in = sys.argv[1]
sys.stderr.write(file_in + "\n")
json_str = file_to_str_proc(file_in)
mqttc = mqtt.Client()
mqttc.on_connect = on_connect
mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)
mqttc.loop_start()
print(len(json_str))
mqttc.publish(MQTT_TOPIC,json_str)
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
subscribe で JSON を受け取るプログラム
#! /usr/bin/python3
#
# subscribe.py
#
# Aug/17/2021
# ------------------------------------------------------------------
import paho.mqtt.client as mqtt
MQTT_HOST = "violet.local"
MQTT_TOPIC = "sample/imageTopic"
MQTT_PORT = 1883 # brokerのport
MQTT_KEEP_ALIVE = 60 # keep alive
#
# ------------------------------------------------------------------
def on_connect(mqttc, obj, flags, rc):
print("rc: " + str(rc))
#
# ------------------------------------------------------------------
def on_message(mqttc, obj, msg):
file_name = "out01.json"
print(msg.topic + " " + str(msg.qos))
str_out = msg.payload.decode()
print(len(str_out))
fp_out = open(file_name,mode='w',encoding='utf-8')
fp_out.write(str_out)
fp_out.close()
# ------------------------------------------------------------------
mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)
mqttc.subscribe(MQTT_TOPIC)
mqttc.loop_forever()
# ------------------------------------------------------------------
JSON を jpg に変換するプログラム
#! /usr/bin/python
#
# json_to_jpg.py
#
# Aug/17/2021
# --------------------------------------------------------------------
import sys
import json
import base64
import numpy as np
import cv2
#
# --------------------------------------------------------------------
file_json = sys.argv[1]
sys.stderr.write(file_json + "\n")
#
fp_in = open(file_json,encoding='utf-8')
json_str = fp_in.read()
fp_in.close()
#
dict_aa = json.loads(json_str)
data_64 = dict_aa["base64"]
file_jpg = dict_aa["filename"]
sys.stderr.write(file_jpg + "\n")
#
sys.stderr.write("len(data) = %d\n" % len(data_64))
#
img_binary = base64.b64decode(data_64)
#
jpg=np.frombuffer(img_binary,dtype=np.uint8)
img = cv2.imdecode(jpg, cv2.IMREAD_COLOR)
cv2.imwrite(file_jpg,img)
#
# --------------------------------------------------------------------
テスト方法
ブローカーは LAN 内の violet.local にあるものを使いました。
RaspberryPi にインストールした mosquitto です。
テストに使った jpg は次の大きさです。
-rw-r--r-- 1 uchida wheel 3870 Aug 17 08:41 camera.jpg
JSON に変換して送信するスクリプト
../jpeg_to_json/jpeg_to_json.py camera
#
../python/publish.py camera.json
別のフォルダーで受信をします。
送信前にこの操作が必要です。
./subscribe.py
受信すると out01.json で作成されます。
jpg に変換します。
./json_to_jpg.py out01.json
camera.jpg が作成されます。
結論
画像の受け渡しが MQTT ブローカー経由でできる。