Q&A
前提
ラズパイ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
1import cv2 2def ccapture(): 3 print("a") 4 cap = cv2.VideoCapture(0) 5 ret, frame = cap.read() 6 cv2.imwrite('./shot/test.jpg', frame)
こちらがapp.py、flask起動用のファイルです
python
1import cv2 2from flask import Flask, render_template, Response 3 4from camera import Camera 5import cameracap 6 7app = Flask(__name__) 8 9 10@app.route("/") 11def index(): 12 return "Hello World!" 13 14@app.route("/stream") 15def stream(): 16 return render_template("stream.html") 17 18def gen(camera): 19 while True: 20 frame = camera.get_frame() 21 22 if frame is not None: 23 yield (b"--frame\r\n" 24 b"Content-Type: image/jpeg\r\n\r\n" + frame.tobytes() + b"\r\n") 25 else: 26 print("frame is none") 27 28@app.route("/video_feed") 29def video_feed(): 30 return Response(gen(Camera()), 31 mimetype="multipart/x-mixed-replace; boundary=frame") 32 33@app.route("/ccaptureh") 34def ccapture(): 35 cameracap.ccapture() 36 print("ok") 37 return render_template("stream.html") 38 39 40if __name__ == "__main__": 41 app.debug = True 42 app.run(host="0.0.0.0", port=5000) 43
試したこと
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
1class Camera(object): 2 def __init__(self): 3 self.video = cv2.VideoCapture(0) 4 5 def __del__(self): 6 self.video.release() 7 8 def get_frame(self,v): 9 success, image = self.video.read() 10 if v == 0: 11 ret, frame = cv2.imencode('.jpg', image) 12 return frame 13 else: 14 cv2.imwrite('test.jpg', image)
app.pyの、一部です。ほかは上記のapp.pyと変わりません
genに引数を渡す処理だけ加えています
python
1@app.route("/ccaptureh") 2def ccapture(): 3 print("ccaptureh!!!!!!!!!!!") 4 Response(gen(Camera(),1)) 5 return render_template("stream.html")
app.pyのgenの改造後です
python
1def gen(camera,v): 2 print(v) 3 while True: 4 frame = camera.get_frame(v) 5 if v == 1:break 6 7 if frame is not None: 8 yield (b"--frame\r\n" 9 b"Content-Type: image/jpeg\r\n\r\n" + frame.tobytes() + b"\r\n") 10 else: 11 print("frame is none")
教えていただいたとおりに、インスタンスを作成し、引数を渡して判断するようにしてみましたが
ストリーミングは今まで通り成功するのですが、撮影が成功しません。どのように直せばいいでしょうか?
回答1件
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2022/07/01 14:07
2022/07/02 09:30