Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
19
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@Motonaga

Pythonで画像データをJSONにしてネットワーク越しに送受信する

はじめに

 Webカメラで撮った画像をHTTPの通信を介して顔検出モデル等が動いている別のサーバーに送信するようなコードを何度か書いたので忘れないようにメモする。
 サンプルコードでは、送信側でWebカメラから撮った画像を一定間隔でサーバに送信し、受信側で顔を検出してボックスを描画した上でローカルに画像ファイルを保存している。

送信側

sender.py
import numpy as np
import cv2
import time
import json
import base64
import requests

def send_image(img):
  # 画像を送信可能な形式に変換してJSONに格納
  _, encimg = cv2.imencode(".png", img)
  img_str = encimg.tostring()
  img_byte = base64.b64encode(img_str).decode("utf-8")
  img_json = json.dumps({'image': img_byte}).encode('utf-8')

  # HTTPリクエストを送信
  response = requests.post("http://localhost:8080/save", data=img_json)
  print('{0} {1}'.format(response.status_code, json.loads(response.text)["message"]))

if __name__ == '__main__':
  cap = cv2.VideoCapture(0)
  cap.set(cv2.CAP_PROP_FPS, 30)
  i = 0
  while True:
    _, img = cap.read()
    if i % 5 == 0:
      send_image(img)
    i += 1

受信側

receiver.py
import os
import json
import cv2
import base64
import numpy as np
from datetime import datetime
from flask import Flask, request, Response
app = Flask(__name__)
count = 0

# 画像を保存するフォルダの作成
image_dir = "./images"
if not os.path.isdir(image_dir):
  os.mkdir(image_dir)

def detect_face(img):
  # 顔検出モデル('haarcascade_frontalface_default.xml')は下記リンクからダウンロードできる
  # https://github.com/opencv/opencv/tree/master/data/haarcascades
  face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
  faces = face_cascade.detectMultiScale(img, 1.3, 5)
  return faces

@app.route('/save', methods=['POST'])
def save_image():
    # データの変換処理
    data = request.data.decode('utf-8')
    data_json = json.loads(data)
    image = data_json['image']
    image_dec = base64.b64decode(image)
    data_np = np.fromstring(image_dec, dtype='uint8')
    decimg = cv2.imdecode(data_np, 1)

    # 顔検出してボックスを描画
    gray_img = cv2.cvtColor(decimg, cv2.COLOR_BGR2GRAY)
    faces = detect_face(gray_img)
    for (x,y,w,h) in faces:
      decimg = cv2.rectangle(decimg,(x,y),(x+w,y+h),(255,0,0),2)

    # 画像ファイルを保存
    global count
    filename = "./images/image{}.png".format(count)
    cv2.imwrite(filename, decimg)
    count += 1

    # HTTPレスポンスを送信
    return Response(response=json.dumps({"message": "{} was saved".format(filename)}), status=200)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

参考

http://edosha.hatenablog.jp/entry/2017/09/05/174453
https://ysss.hateblo.jp/entry/2018/07/31/053507

19
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
19
Help us understand the problem. What is going on with this article?