思ったより難しくありませんでした。
地下鉄円山公園駅のバスターミナルから直通のバスが走ってました。
回収完了。
なかなか景色が良いです。
ちなみに、北海道神宮(円山公園内)もチェックポイントがあったので、ついでに回収しました。
リスがおりました。
前回は、Webページをローカルで作成して、そこからブラウザに表示させていたのですが、
今回はWebページをラズパイに設置して、ブラウザからラズパイにアクセスすることによってプレビュー画面を表示させたいと思います。
動作はURLのパスによって変えます。
パスが”/”ならば、Webページを、”/Streaming”ならカメラの画像を返すようにします。
まず、Pythonのコードはこうなりました。
import base64
import cv2
import json
import os
import sys
import time
import threading
from http.server import BaseHTTPRequestHandler
from http.server import HTTPServer
from http import HTTPStatus
from urllib.parse import urlparse
PORT = 8000
cap = cv2.VideoCapture(0)
def __main__():
thread = threading.Thread(target=httpServe)
thread.start()
try:
while cap.isOpened():
time.sleep(1)
except KeyboardInterrupt:
return
def httpServe():
handler = StubHttpRequestHandler
httpd = HTTPServer(('',PORT),handler)
httpd.serve_forever()
class StubHttpRequestHandler(BaseHTTPRequestHandler):
server_version = "HTTP Stub/0.1"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def do_GET(self):
parsed = urlparse(self.path)
if parsed.path == '/Streaming':
enc = sys.getfilesystemencoding()
_, img = cap.read()
resized_img = cv2.resize(img, (480, 320))
_, encoded_img = cv2.imencode('.jpg', resized_img, [int(cv2.IMWRITE_JPEG_QUALITY), 30])
dst_base64 = base64.b64encode(encoded_img).decode('utf-8')
data = {
'image': 'data:image/jpg;base64,' + dst_base64
}
encoded = json.dumps(data).encode()
self.send_response(HTTPStatus.OK)
self.send_header("Content-type", "text/html; charset=%s" % enc)
self.send_header("Access-Control-Allow-Origin", "null")
self.send_header("Content-Length", str(len(encoded)))
self.end_headers()
self.wfile.write(encoded)
elif parsed.path == '/vue.min.js':
self.send_response(HTTPStatus.OK)
with open('vue.min.js',mode='br') as f:
data = f.read()
self.send_header("Content-type", "text/javascript")
self.end_headers()
self.wfile.write(bytes(data))
elif parsed.path == '/jquery-3.5.1.slim.min.js':
self.send_response(HTTPStatus.OK)
with open('jquery-3.5.1.slim.min.js',mode='br') as f:
data = f.read()
self.send_header("Content-type", "text/javascript")
self.end_headers()
self.wfile.write(bytes(data))
else:
self.send_response(HTTPStatus.OK)
with open('index.html',mode='br') as f:
data = f.read()
self.send_header("Content-type", "text/html; charset=utf-8")
self.end_headers()
self.wfile.write(bytes(data))
__main__()
無駄にでかくなった気がする。
というのも、使用しているjsファイルもラズパイからGETしようとブラウザが動くので、jsファイルを送るように作成しないといけないのです。
めんどくさいから、他のライブラリを使用することも考えないといかんなぁ。
続いて、html側。
こちらはそんなに難しくはない。
URLを変えるだけなので。
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="vue.min.js"></script>
<script src="jquery-3.5.1.slim.min.js"></script>
</head>
<body>
<div id="app">
<image id="camera" src="" />
</div>
<script>
var app = new Vue({
el: '#app',
data: {
timer: null,
},
created: function() {
self = this;
this.timer = setInterval(function() {self.onLoad()}, 50)
},
methods: {
onLoad: function() {
axios.get('http://pi4.local:8000/Streaming').then(function(response){
$("#camera").attr('src', response.data.image);
}).catch(function(error){
});
}
}
})
</script>
</body>
</html>
これで動作しました。