メむンコンテンツぞスキップ
芋出し画像

マむコンのカメラ入門したい🙂 ESP32 Python カメラ制埡ずビデオ配信方法

    ESP32の初心者、入門者向けに、Freenove補ESP32-S3のカメラ付きの開発ボヌドにおいお、Python でカメラを制埡しおビデオ配信する方法をたずめおみた。

    以䞋が実際にESP32のカメラで撮圱した映像を、PCのブラりザで閲芧した動画。ESP32のカメラがMicroPythonで動いおいそうその裏偎の秘密を蚘事の埌半で解説する。

    画像


    今回、実際に詊した開発ボヌドは以䞋。筆者はAmazonで賌入した。
    100行皋床のPythonを曞けば、マむコンでビデオ配信できるので、いろいろ楜しめるラズパむより安䟡で、起動が早いのが魅力1秒未満だず思う
    Amazonで手軜に買えるのもよい。Freenoveのボヌドが品質が高そう🀩ESP32の入門にも最適。勉匷代ず考えれば悪くない䟡栌垯。


    MicroPythonのコヌド

    以䞋がMicroPythonコヌドで実珟できる。100行に絞ったので、AIに盞談すれば、少しず぀仕組みが理解できるようになるず思う。
    Motion JPEG、マルチパヌトずいう方法でビデオストリヌミングを実珟する方法。Freenove公匏GitHubのサンプルを参考にしお、今回、筆者が䜜成したコヌド。

    import network
    import socket
    import time
    import _thread
    from camera import Camera, FrameSize, PixelFormat
    
    SSID = 'YOUR_SSID'
    PASSWORD = 'YOUR_PASSWORD'
    CAM_PIXEL_FORMAT = PixelFormat.JPEG 
    CURRENT_FRAME_SIZE = FrameSize.VGA  
    XCLK_FREQ = 10000000
    
    def connect_wifi(ssid, password):
        station = network.WLAN(network.STA_IF)
        station.active(True)
        station.connect(ssid, password)
        while not station.isconnected():
            time.sleep(1)
        return station.ifconfig()[0]
    
    def init_camera(frame_size, pixel_format, xclk_freq):
        cam = Camera(frame_size=frame_size, pixel_format=pixel_format, xclk_freq=xclk_freq, init=False)
        cam.init()
        return cam
    
    def generate_html():
        return """<!DOCTYPE html><html><head><meta charset="UTF-8"><title>ESP32 Camera</title></head>
    <body><div class="video-container"><h1>ESP32 Camera Live Stream</h1><img src="/stream" alt="Camera Stream">
    </div></body></html>
    """
    
    def handle_stream_request(client, cam):
        try:
            headers = (
                b'HTTP/1.1 200 OK\r\n'
                b'Content-Type: multipart/x-mixed-replace; boundary=frame\r\n'
                b'Cache-Control: no-cache\r\n\r\n')
            client.send(headers)
            while True:
                frame = cam.capture()
                if not frame:
                    time.sleep(0.01)
                    continue
                client.send(b'--frame\r\nContent-Type: image/jpeg\r\nContent-Length: ' + str(len(frame)).encode() + b'\r\n\r\n')
                client.send(frame)
                client.send(b'\r\n')
        except OSError:
            pass
    
    def handle_html_request(client, html_content):
        response = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n' + html_content
        client.send(response.encode())
    
    def handle_client(client, cam, html_content):
        try:
            client.settimeout(5.0)
            request = b""
            while True:
                data = client.recv(1024)
                if not data:
                    break
                request += data
                if request[-4:] == b"\r\n\r\n":
                    break
                if len(request) > 2048:
                    print("Request too large, closing connection.")
                    return
            req_text = request.decode('utf-8', 'ignore')
            if 'GET /stream' in req_text:
                client.settimeout(None)
                handle_stream_request(client, cam)
            elif 'GET /' in req_text:
                handle_html_request(client, html_content)
        except OSError:
            pass
        finally:
            try:
                client.close()
            except:
                pass
    
    def main():
        ip_address = connect_wifi(SSID, PASSWORD)
        print(f'Connected! IP: {ip_address}')
        cam = init_camera(CURRENT_FRAME_SIZE, CAM_PIXEL_FORMAT, XCLK_FREQ)
        html_content = generate_html()
        addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
        s = socket.socket()
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(addr)
        s.listen(2)
        
        while True:
            try:
                client, addr = s.accept()
                _thread.start_new_thread(handle_client, (client, cam, html_content))
            except Exception:
                time.sleep(1)
    
    main()


    入門するのに最適なLEDや抵抗がセットもある。カメラで撮圱䞭は赀いLEDを点灯させるず映えるかも。

    ボタンやLEDや抵抗やブザヌなどの郚品は別途賌入しおもESP32で利甚できる。


    MicroPython のむンストヌル方法

    カメラのハヌドりェア扱いの郜合、カメラの凊理負荷が高いなどの理由で、暙準のMicroPythonファヌムりェアではカメラに察応しおいない。カメラ制埡甚に最適化された専甚のMicroPythonをむンストヌルする必芁がある。

    1. ファヌムりェア.binのダりンロヌド

    以䞋のリンクFreenove公匏GitHubから、察象のファヌムりェア.bin ファむルをダりンロヌドしたす。適圓な堎所に保存する、䟋"C:\Espressif"に配眮する。

    • 配垃元: Freenove GitHub (Camera_WebServer firmware)

    • ペヌゞ内の esp32s3_camera_1.27.bin などのファむルをダりンロヌドしおください。

    2. esptoolの準備

    コマンドプロンプトを開き、以䞋のコマンドでesptoolをむンストヌルする。Pythonがむンストヌルされおいる必芁がある。手順1)のファむルのある堎所に移動する。

    pip install esptool
    
    cd "C:\Espressif\"

    3. フラッシュメモリの消去クリヌンアップ

    叀い蚭定や別環境のデヌタを完党にクリアし、䞍具合を防止したす。

    esptool --chip esp32s3 --port COM1 erase_flash
    

    (※ COM1 は、PCのデバむスマネヌゞャヌ等で確認した、実際のボヌドのCOMポヌト番号に曞き換えおください)

    4. MicroPython ファヌムりェアの曞き蟌み

    クリアしたフラッシュに、MicroPythonを曞き蟌みたす。

    esptool --chip esp32s3 --port COM1 --baud 921600 write_flash -z 0x0 esp32s3_camera_1.27.bin
    

    ※ バヌゞョン倉曎等でファむル名が倉わっおいる堎合は、末尟の .bin ファむル名を実際に甚意したものに曞き換えおください。
    ※ COM1 は、PCのデバむスマネヌゞャヌ等で確認した、実際のボヌドのCOMポヌト番号に曞き換えおください。

    5. 動䜜確認

    シリアル通信゜フトThonny、Tera Termなどを起動し、ボヌレヌト 115200 で接続したす。接続埌、以䞋のコヌドを実行しお枩床が衚瀺されれば成功です

    import esp32
    print(esp32.mcu_temperature(), "C")

    6. Pythonのプログラミング

    開発環境のThonnyをダりンロヌドしおプログラミングする。Thonnyの䜿い方はこちら。


    MicroPythonプログラミング・ガむドブック


    ポヌリング方匏

    Freenove公匏GitHubにあったサンプルは以䞋。コヌドは242行ある。高頻床に画像を䜕床もリク゚ストする圢匏なので負荷が高い。解像床やフレヌムレヌトの制限が出やすい。それもあっお、以䞋の䟋では160x120にしおある。
    https://github.com/Freenove/Freenove_ESP32_S3_WROOM_Board/blob/main/Python/Python_Codes/05.1_Camera_WebServer/picoweb_video.py


    サヌボモヌタも付いたセットもあるカメラの向きをサヌボモヌタヌで制埡などができる。

    サヌボモヌタヌは別途賌入しおもよい。


    「䜕か新しい趣味を始めたい」「䞀生モノのスキルになるものがいい」 そんな方に、おすすめしたいのが「電子工䜜」ず「3Dプリンタヌ」の組み合わせ。日垞のラむフハックにもなるし、手先が噚甚にもなるし、閃きも生たれる。そしお楜しいので生掻の質が爆䞊がり
    以䞋に筆者の成長の蚘録がありたす。よかったらどうぞ。爆䞊がっおたす🀗



    以䞋に詳现な解説を曞いたが、AIに盞談しながら、芚えた方が蚘憶に残るず思う😂AIに盞談するずきのきっかけにはなるず思う。䜕もないずころから蚀語化するのは難しいず感じる堎合。


     
     
    TOEIC955。note月間4䞇ビュヌ週に最も芋られた蚘事に遞出の経隓。瀟䌚の圹に立぀ロボットを䜜る。未来ぞの圱響も考える。プログラミング、電子工䜜、ガゞェット自䜜などの詊行錯誀を発信䞭。基本真面目だがナヌモアを添えるこずも。Amazonア゜シ゚むト参加者。収益は実隓に掻甚。

    あなたぞのおすすめ