前提
ラズパイZero、Python、Flask、Opencvを使ってWeb上から確認できるカメラを作っています
ストリーミングで常に確認でき、キャプチャーボタンを押したら今写っているところを画像として保存するようにしたいです
実現したいこと
現在、カメラの映像をWeb上からストリーミングで見ることはできるようになりました
https://qiita.com/RIckyBan/items/a7dea207d266ef835c48
こちらのサイトを参考にしました
そこで今写っている映像をキャプチャーし、画像ファイルとして「shot」フォルダに保存したいです
発生している問題・エラーメッセージ
Opencvでカメラを撮影する方法を調べ、それをPythonファイルにし、Captureボタンを押したらそのPythonファイルを実行したいのですが、すると下記のようなエラーが出てしまいます
Traceback (most recent call last) File "/home/〇〇/.local/lib/python3.9/site-packages/flask/app.py", line 2095, in __call__ return self.wsgi_app(environ, start_response) File "/home〇〇/.local/lib/python3.9/site-packages/flask/app.py", line 2080, in wsgi_app response = self.handle_exception(e) File "/home/〇〇/.local/lib/python3.9/site-packages/flask/app.py", line 2077, in wsgi_app response = self.full_dispatch_request() File "/home/〇〇/.local/lib/python3.9/site-packages/flask/app.py", line 1525, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/〇〇/.local/lib/python3.9/site-packages/flask/app.py", line 1523, in full_dispatch_request rv = self.dispatch_request() File "/home/〇〇/.local/lib/python3.9/site-packages/flask/app.py", line 1509, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "/home/〇〇/cflask/app.py", line 35, in ccapture cameracap.ccapture() File "/home/〇〇/cflask/cameracap.py", line 8, in ccapture cv2.imwrite('./shot/test.jpg', frame) cv2.error: OpenCV(4.6.0) /tmp/pip-wheel-u79916uk/opencv-python_ea2489746b3a43bfb3f2b5331b7ab47a/opencv/modules/imgcodecs/src/loadsave.cpp:801: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'
該当のソースコード
こちらがcameracap.py、撮影用のPythonファイルです
python
import cv2 def ccapture(): print("a") cap = cv2.VideoCapture(0) ret, frame = cap.read() cv2.imwrite('./shot/test.jpg', frame)
こちらがapp.py、flask起動用のファイルです
python
import cv2 from flask import Flask, render_template, Response from camera import Camera import cameracap app = Flask(__name__) @app.route("/") def index(): return "Hello World!" @app.route("/stream") def stream(): return render_template("stream.html") def gen(camera): while True: frame = camera.get_frame() if frame is not None: yield (b"--frame\r\n" b"Content-Type: image/jpeg\r\n\r\n" + frame.tobytes() + b"\r\n") else: print("frame is none") @app.route("/video_feed") def video_feed(): return Response(gen(Camera()), mimetype="multipart/x-mixed-replace; boundary=frame") @app.route("/ccaptureh") def ccapture(): cameracap.ccapture() print("ok") return render_template("stream.html") if __name__ == "__main__": app.debug = True app.run(host="0.0.0.0", port=5000)
試したこと
shotフォルダは同じフォルダに存在します。
png、jpgどちらもだめでした
補足情報(FW/ツールのバージョンなど)
python3.9.2
opencv 4.6.0
flask 2.1.2
ラズパイZero
これが環境です
どなたか教えていただけると幸いです
追記 07/01
教えていただきありがとうございます
genという関数に引数を一つ渡し、その引数でcamera.pyのほうにストリーミングか撮影かを判断させるように改造してみました
しかし、そもそもカメラが見つからないという「can't open camera by index」のエラーがでてその先が止まってしまいます
camera.pyの中身です
Python
class Camera(object): def __init__(self): self.video = cv2.VideoCapture(0) def __del__(self): self.video.release() def get_frame(self,v): success, image = self.video.read() if v == 0: ret, frame = cv2.imencode('.jpg', image) return frame else: cv2.imwrite('test.jpg', image)
app.pyの、一部です。ほかは上記のapp.pyと変わりません
genに引数を渡す処理だけ加えています
python
@app.route("/ccaptureh") def ccapture(): print("ccaptureh!!!!!!!!!!!") Response(gen(Camera(),1)) return render_template("stream.html")
app.pyのgenの改造後です
python
def gen(camera,v): print(v) while True: frame = camera.get_frame(v) if v == 1:break if frame is not None: yield (b"--frame\r\n" b"Content-Type: image/jpeg\r\n\r\n" + frame.tobytes() + b"\r\n") else: print("frame is none")
教えていただいたとおりに、インスタンスを作成し、引数を渡して判断するようにしてみましたが
ストリーミングは今まで通り成功するのですが、撮影が成功しません。どのように直せばいいでしょうか?
まだ回答がついていません
会員登録して回答してみよう