4
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?

M5Stack Module LLM Advent Calendar 2024

Day 5

Module-LLMにUSBカメラを接続する

Last updated at Posted at 2024-12-04

目的

Module-LLMにUSBカメラを接続してストリーミング配信、PCのブラウザから確認します。

Module-LLMのType-Cポートについて

Module-LLMのType-Cポートは、USBホストになっているため、USBデバイスを接続することができます。
LLMモジュールと使用する場合は、デバイスがType-CのOTG規格に準拠している必要があります。LLMモジュールのUSB Type-Cポートは、Type-Cコントローラー(SGM7220)によってOTG規格をサポートしています。
接続するUSBハブやUSBデバイスがOTG規格に対応していない場合は接続されたポートの検出に失敗します。

Module-LLMのType-Cポートについて

image.png

Module-LLMのType-Cポートに、Daisoの薄型Type-CポートとemeetのC960カメラを接続しました。
lsusbで認識できていることが確認できました。
Daisoの薄型Type-Cポートは、"Linux Foundation 3.0 root hub"と"Linux Foundation 2.0 root hub"という名前で表示されています。emeetのC960カメラは、"EMEET HD Webcam eMeet C960"という名前で表示されています。

root@m5stack-LLM # lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 328f:006d EMEET HD Webcam eMeet C960
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

USBカメラの画像をストリーミング配信を行う。

Module-LLMのUbuntu OSへ、rootアカウントからログインし、pipでOpenCVとFastAPIをインストールします。
その後に、以下のPythonプログラムを実行します。

root@m5stack-LLM # pip install fastapi opencv-python uvicorn
root@m5stack-LLM # python3 send_uvc_streaming.py
send_uvc_streaming.py
from fastapi import FastAPI, Response
from fastapi.responses import StreamingResponse
import cv2
import numpy as np
from typing import Generator
import time

app = FastAPI()

def resize_frame(frame: np.ndarray, width: int = 320, height: int = 240) -> np.ndarray:
    return cv2.resize(frame, (width, height), interpolation=cv2.INTER_AREA)

def get_video_stream() -> Generator[bytes, None, None]:
    camera = cv2.VideoCapture(0)

    try:
        while True:
            success, frame = camera.read()
            if not success:
                break

            frame = resize_frame(frame)
            time.sleep(0.005)
            _, buffer = cv2.imencode('.jpg', frame)
            yield (b'--frame\r\n'
                  b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n')
    finally:
        camera.release()

@app.get("/video")
async def video_endpoint():
    return StreamingResponse(
        get_video_stream(),
        media_type='multipart/x-mixed-replace; boundary=frame'
    )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8888)
4
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
4
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?