【ラズベリーパイ】カメラモジュールの映像をネットワーク経由で別PCに表示する方法
作成日時: | 2019年11月6日 |
更新日時: | 2020年4月22日 |
ラズベリーパイのカメラモジュールで撮影した映像を同一ネットワーク内の別PCで表示する方法を解説します。
完成形は下の動画のようになります。
コードのポイントは、ラグを減らすためラズパイ側でJPEG圧縮をしてからTCPで送信し、受信側で復元することです。
そうしないとラグがひどくなります。
それと、ラズパイ側でプログラムを実行する前に以下のコマンドを実行する必要があります。
以下コード全文です。
ラズパイ側
PiCamera streaming on Tkinter label -Help
完成形は下の動画のようになります。
そうしないとラグがひどくなります。
それと、ラズパイ側でプログラムを実行する前に以下のコマンドを実行する必要があります。
sudo modprobe bcm2835-v4l2このコマンドについては良くわからないのですが、また調べて記事にしてみます。
以下コード全文です。
ラズパイ側
import socket
import cv2
import time
SERVER_PORT = 58372
FRAME_WIDTH = 300
FRAME_HEIGHT = 300
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("", SERVER_PORT))
server.listen()
soc, addr = server.accept()
vcap = cv2.VideoCapture(0)
while True:
_, frame = vcap.read()
resized_frame = cv2.resize(frame, (FRAME_WIDTH, FRAME_HEIGHT))
print(type(resized_frame))
status, encoded_img = cv2.imencode(".jpg", resized_frame, [int(cv2.IMWRITE_JPEG_QUALITY), 30])
print(len(encoded_img), "bytes (encoded)")
data = encoded_img.tostring()
header_size = 4
header = len(data).to_bytes(header_size, "big")
soc.sendall(header + data)
print(len(data), "bytes sended")
time.sleep(0.015)
別PC側import socket
import tkinter
import numpy as np
import PIL.Image, PIL.ImageTk
import cv2
import threading
def update_image(data):
global photo
img = np.frombuffer(data, dtype=np.uint8)
img = cv2.imdecode(img, 1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(img))
canvas.create_image(0, 0, image = photo, anchor = tkinter.NW)
def update_loop():
data = b""
while True:
data += client.recv(BUFSIZE)
if len(data) < 4:
continue
data_size = int.from_bytes(data[:4], "big")
buf = data[4:]
while True:
if len(buf) > data_size:
img_data = buf[0 : data_size]
update_image(img_data)
data = buf[data_size : ]
break
else:
buf += client.recv(BUFSIZE)
SERVER_IP = "192.168.0.2" # ★★★ラズパイのIPアドレスを指定してください!!!
SERVER_PORT = 58372
BUFSIZE = 270000
window = tkinter.Tk()
canvas = tkinter.Canvas(window, width=300, height=300)
canvas.pack()
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((SERVER_IP, SERVER_PORT))
thread = threading.Thread(target=update_loop)
thread.start()
window.mainloop()
実行する場合は、まずラズパイの方のプログラムを実行し、そのあと別PC側のプログラムを実行してください。参考にしたサイト
Pythonでネットワーク越しにカメラの映像をストリーミングPiCamera streaming on Tkinter label -Help