Python

Python - AWS 서버와 라즈베리파이 TCP 소켓 통신

염지미 2023. 10. 20. 18:07

AWS(ubuntu) Server & Raspberrypi

라즈베리파이의 파이카메라를 통해 AWS 서버에 전달하여 실시간 스트리밍 서비스

파이썬의 requests 라이브러리의 TCP 소켓 통신을 활용한 데이터 전송

AWS(ubuntu) Server.py

from flask import Flask, request, Response, jsonify
from urllib.parse import urlencode, unquote
from PIL import Image
import numpy as np
import cv2

frame_data = 0

def gen():
    while True:
        global frame_data
    
        yield (b'--frame\r\n'
            b'Content-Type: image/jpeg\r\n\r\n' + frame_data + b'\r\n')

# 라즈베리 파이에서 POST 요청을 수신하여 영상 처리 및 스트리밍
@app.route('/video_feed', methods=['GET', 'POST'])
def video_feed():
    return Response(gen(), mimetype="multipart/x-mixed-replace; boundary=frame")

# 라즈베리 파이에서 POST 요청을 수신하여 영상 처리 및 스트리밍
@app.route('/endpoint', methods=['POST'])
def video_save():
    global frame_data
    # POST 요청에서 이미지 데이터를 읽어옵니다.
    image_data = request.data
    image_array = np.frombuffer(image_data, dtype=np.uint8)
    
    # 이미지 데이터를 OpenCV 형식으로 변환
    frame = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
    
    # OpenCV 이미지를 PIL 이미지로 변환
    image_pil = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    image_pil.save('captured_image.jpg', 'JPEG') 
    
    with open('captured_image.jpg', 'rb') as file:
        frame_data = file.read()
    response_data = {"message": "success"}
    return jsonify(response_data)

 


Raspberrypi Client.py

import io
import picamera
import requests
from PIL import Image

# AWS 서버 엔드포인트 URL 설정
aws_server_url = 'http://192.0.0.1:5000/endpoint'

# 카메라 초기화
camera = picamera.PiCamera()
camera.resolution = (640, 480)

# 스트리밍 루프
try:
    stream = io.BytesIO()
    for _ in camera.capture_continuous(stream, format='jpeg'):
        # 이미지 데이터를 AWS 서버로 전송
        response = requests.post(aws_server_url, data=stream.getvalue())
        if response.status_code == 200 and response.json()["message"] == "success":
            print('이미지 전송 성공')
        else:
            print('이미지 전송 실패:', response.status_code, response.text)
        stream.seek(0)
        stream.truncate()
finally:
    camera.close()