I have the following code at the end of my Flask Script:
while True:
success, img = video.read()
image = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(image, lower, upper)
blur = cv2.GaussianBlur(mask, (15, 15), 0)
circles = cv2.HoughCircles(blur, cv2.HOUGH_GRADIENT, 1, 14,
param1=34, param2=10, minRadius=4, maxRadius=10)
circles = np.uint16(np.around(circles))
# Check if a new round has started
if (len(circles[0, :]) == 7) and not is_round:
start_time = time.time() # Start time
is_round = True
curr_count = 0
round_total = 0
elif is_round:
if len(circles[0, :]) == 1:
end_time = time.time()
is_round = False
time_taken = end_time - start_time
print('Round time: ', str(
datetime.timedelta(seconds=time_taken))[2:7])
times.append(time_taken)
average = sum(times) / len(times)
print('Average time: ', str(
datetime.timedelta(seconds=average))[2:7])
elif len(circles[0, :]) < 7:
curr_count = (7 - round_total) - len(circles[0, :])
total = curr_count
round_total = curr_count
for i in circles[0, :]:
# draw the outer circle
cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)
Tracking()
return render_template('theme1.html', output2=total)
if __name__ == "__main__":
app.run(debug=True)
The Tracking() does not repeat the script because it is blocked by render_template and app.run, how do i make it so the python script runs continuously? Thanks! EDIT: I have added more of the code, if anyone has a solution please tell me.
CodePudding user response:
HTTP views, i.e. @app.route(...)
, are not designed for continuous data transmission like video streaming. That's what websockets are for.
Your program architecture needs to be changed so that:
The HTTP endpoint
"/"
will send a webpage that does not contain any image. Instead, it should contain a javascript code (in<script>
tag) that will connect to a websocket from the browser, and display the video. This tutorial may help you.In your python code you need to create a websocket endpoint (that will be called using
ws://...
instead ofhttp://...
). The endpoint should accept connections and start streaming images to them. In practice it would look like thewhile
loop that you already have, but the data will be send to the socket.
CodePudding user response:
You can keep the same code but you need to break it into 2 functions. One that continuously updates a shared variable with the number of object (and it should run in a separate thread to avoid blocking), and another one that returns the variable in a webpage.
The structure should look like this:
from threading import Thread
...
app = Flask(__name__)
output_state = None
def output_updater_loop():
nonlocal output_state # important
...
video = cv2.VideoCapture(1, 0)
...
while True:
success, img = video.read()
...
output_state = ...
@app.route("/")
def get_page():
return render_template(..., output_state=output_state)
output_updater_thread = Thread(
name='output_updater_thread',
target=output_updater_loop,
daemon=True
)
output_updater_thread.start() # Won't block
app.run(debug=True)
After you can do this, you can improve the code by using a mutex on output_state. Learn more: https://en.wikipedia.org/wiki/Thread_safety