Issue in terminating a loop - python

I have the following code reading more frames than are in the folder. I am facing issue to stop when all the images are read from a folder instead of going again in the loop and reading the frames again I need to stop this cycle.
IMAGE_FOLDER="frames"
filenames = [f"{IMAGE_FOLDER}/frame{i}.jpg" for i in range(1, 2522)]
filenames = ["{}/frame{}.jpg".format(IMAGE_FOLDER,i) for i in range(1, 2522)]
SERVER_A_ADDRESS = "tcp://localhost:5555"
context = zmq.Context()
socket_server_a = context.socket(zmq.PUSH)
socket_server_a.connect(SERVER_A_ADDRESS)
destination = {
"currentSocket": socket_server_a,}
running = True
endpoint_responses = 0
frames= 0
def send_frame(frame, frame_requests):
global destination, running
try:
frame = cv2.resize(frame, (224, 224))
encoded, buffer = cv2.imencode('.jpg', frame)
jpg_as_text = base64.b64encode(buffer)
print("{} ( i ) : Sending frame {} to {}...".format(time.strftime('%H:%M:%S'),frame_requests))
destination["currentSocket"].send(jpg_as_text)
except Exception as Error:
print("{} ( ! ) : Encountered Error at frame {}\n\n> KILLING CONNECTIONS\n\nERROR MESSAGE: {Error}".format(time.strftime('%H:%M:%S'),frame_requests,Error))
running = False
def main():
global destination, running, frames
interval = 1 / 10
while running:
for img in filenames:
frames = cv2.imread(img)
frames += 1
print("{} ( i ) : frames count = {}".format(time.strftime('%H:%M:%S'),frames))
threading.Thread(target=send_frame, args=(frame, frames)).start()
time.sleep(interval)
destination["currentSocket"].close()
if __name__ == "__main__":
main()
Thanks help is highly appreciated

You are missing to assign running = Fasle one the loop is done.
Try this instead:
def main():
global destination, running, frames
interval = 1 / 10
while running:
for img in filenames:
frames = cv2.imread(img)
frames += 1
print("{} ( i ) : frames count = {}".format(time.strftime('%H:%M:%S'),frames))
threading.Thread(target=send_frame, args=(frame, frames)).start()
time.sleep(interval)
running = False
destination["currentSocket"].close()

Related

Save a video with different file name each time we give a Trigger in opencv

This is the process I am trying to achieve :
Live Stream is captured from webcam and the Image frames are stored in a particular folder.
Now, If I give a trigger the frames in that folder at that moment should be converted into a video and get saved with name eg. video1.mp4.
Now again if I press a trigger another video should be saved as video2.mp4.
I have attached the code here . If I press R , it is saving one video as a0.mp4 . But If I press again, nothing seems to happen.
def frametovideo(img_array):
for i in range(len(img_array)):
out.write(img_array[i])
if name == "main":
img_array = []
videono = 0
cap = cv2.VideoCapture(0)
for filename in glob.glob('./output/*.jpg'):
img = cv2.imread(filename)
height, width, layers = img.shape
size = (width,height)
img_array.append(img)
path = 'a' + str(videono) + '.mp4'
out = cv2.VideoWriter(path,cv2.VideoWriter_fourcc(*'mp4v'), 15, size)
while True:
ret, frame = cap.read()
if ret == True:
cv2.imshow("frame",frame)
k = cv2.waitKey(5) & 0xff
if k == ord('r'):
frametovideo(img_array)
videono += 1
You do not understanding how to save filenames Do not used operator. Used string format python 3.8 or later. Try this in below. Actually, you can modified key press.
import cv2
import os
i = 1
wait = 0
video = cv2.VideoCapture(0)
while video.isOpened():
ret, img = video.read()
cv2.imshow('live video', img)
# wait for user to press any key
key = cv2.waitKey(100)
# wait variable is to calculate waiting time
wait = wait+100
if key == ord('q'):
break
# when it reaches to 5000 milliseconds
# we will save that frame in given folder
if wait == 5000:
filename = f'Frame_{str(i)}.jpg'
# Save the images in given path
cv2.imwrite(filename, img)
i += 1
wait = 0
# close the camera
video.release()
# close open windows
cv2.destroyAllWindows()
Btw,look in line #27-34. Correct way to do this if __name__ == "__main__":

How to integrate OpenCV webcam with Django and React?

I have a barcode reader which I implemented by using opensource Dynamsoft API and OpenCV.
Now I need to integrate it with Django and display on my website in React.
I have no idea how to do that, I tried passing the code to my views.py but don't know what I should do next.
Here is my code for barcode reading:
import cv2
from dbr import *
import time
reader = BarcodeReader()
def text_results_callback_func(frame_id, t_results, user_data):
print(frame_id)
for result in t_results:
text_result = TextResult(result)
print("Barcode Format : ")
print(text_result.barcode_format_string)
print("Barcode Text : ")
print(text_result.barcode_text)
print("Exception : ")
print(text_result.exception)
print("-------------")
def get_time():
localtime = time.localtime()
capturetime = time.strftime("%Y%m%d%H%M%S", localtime)
return capturetime
def read_barcode():
video_width = 0
video_height = 0
vc = cv2.VideoCapture(0)
video_width = vc.get(cv2.CAP_PROP_FRAME_WIDTH)
video_height = vc.get(cv2.CAP_PROP_FRAME_HEIGHT)
vc.set(3, video_width)
vc.set(4, video_height)
stride = 0
if vc.isOpened():
rval, frame = vc.read()
stride = frame.strides[0]
else:
return
windowName = "Barcode Reader"
parameters = reader.init_frame_decoding_parameters()
parameters.max_queue_length = 30
parameters.max_result_queue_length = 30
parameters.width = video_width
parameters.height = video_height
parameters.stride = stride
parameters.image_pixel_format = EnumImagePixelFormat.IPF_RGB_888
parameters.region_top = 0
parameters.region_bottom = 100
parameters.region_left = 0
parameters.region_right = 100
parameters.region_measured_by_percentage = 1
parameters.threshold = 0.01
parameters.fps = 0
parameters.auto_filter = 1
reader.start_video_mode(parameters, text_results_callback_func)
while True:
cv2.imshow(windowName, frame)
rval, frame = vc.read()
if rval == False:
break
try:
ret = reader.append_video_frame(frame)
except:
pass
key = cv2.waitKey(1)
if key == ord('q'):
break
reader.stop_video_mode()
cv2.destroyWindow(windowName)
print("-------------------start------------------------")
reader.init_license("***************************")
read_barcode()
I think you need to use the JS version of Dynamsoft Barcode Reader to scan barcodes using cameras in a webpage: https://www.dynamsoft.com/barcode-reader/sdk-javascript/

Stop video by its play time

I created a program to extract the video into frames.I need suggestion to stop the cv2.imshow() after when there is no more frames to show.
video frames count = 88
fps = 10.0
duration= int(8)
def reading_video():
read_input = cv2.VideoCapture(r"D:\data\input.mp4")
frame_rate = int(read_input.get(cv2.CAP_PROP_FRAME_COUNT)) # 88
print("total number of frames is ", frame_rate)
fps = read_input.get(cv2.CAP_PROP_FPS) #10.0
duration = int((frame_rate/fps) %60)# 8
print(duration) # 8.0
initial_frame = 0
while read_input.isOpened():
ret, frame = read_input.read()
if ret == True:
cv2.imshow('video_frame', frame)
write_path = r"D:\data\frame_output"
write_name = 'frame0' + str(initial_frame) + '.jpg'
cv2.imwrite(os.path.join(write_path, write_name), frame)
initial_frame += 1
if cv2.waitKey(0) & 0xFF == ord('c'):
break
else:
break
instance_variable = reading_video()
instance_variable.release()
cv2.destroyAllWindows()
If waitkey(int(duration)) then it played and after no frame i do getting cv2 Assertion error.
If waitkey(0) then i do getting AttributeError: 'NoneType' object has no attribute 'release'
reading_video() doesn't uses return so it returns None and you have
instance_variable = None
and later
None.release()
Inside reading_video() you should use
return read_input
or maybe even directly
read_input.release()
without instance_variable.release()

How do you perform Multithreaded Frame Extraction in Python with OpenCV?

Hi Stackoverflow Users,
I'm currently trying to perform a multithreaded frame extraction using OpenCV. I've made such multithreaded operations before on other tasks, but for some reason it doesnt seem to work on the frame extraction. This is my Code:
import cv2
import os
import face_recognition
from PIL import Image
import multiprocessing
try:
if not os.path.exists('frames'):
os.makedirs('frames')
except OSError:
print('Error: Creating directory of frames')
try:
if not os.path.exists('faces'):
os.makedirs('faces')
except OSError:
print('Error: Creating directory of faces')
def frame_extract_1():
currentFrame_extract = 1
video_capture = cv2.VideoCapture("DOLFACE_1.mp4")
while(True):
ret1, frame = video_capture.read()
if ret1 == False:
break
name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
print(f"Processor 1 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
cv2.imwrite(name, frame)
currentFrame_extract += 4
video_capture.release()
cv2.destroyAllWindows()
def frame_extract_2():
currentFrame_extract = 2
video_capture = cv2.VideoCapture("DOLFACE_1.mp4")
while(True):
ret2, frame = video_capture.read()
if ret2 == False:
break
name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
print(f"Processor 2 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
cv2.imwrite(name, frame)
currentFrame_extract += 4
video_capture.release()
cv2.destroyAllWindows()
def frame_extract_3():
currentFrame_extract = 3
video_capture = cv2.VideoCapture("DOLFACE_1.mp4")
while(True):
ret3, frame = video_capture.read()
if ret3 == False:
break
name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
print(f"Processor 3 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
cv2.imwrite(name, frame)
currentFrame_extract += 4
video_capture.release()
cv2.destroyAllWindows()
def frame_extract_4():
currentFrame_extract = 4
video_capture = cv2.VideoCapture("DOLFACE_1.mp4")
while(True):
ret4, frame = video_capture.read()
if ret4 == False:
break
name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
print(f"Processor 4 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
cv2.imwrite(name, frame)
currentFrame_extract += 4
video_capture.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
video_file_path = "DOLFACE_1.mp4"
frame_extractor_1 = multiprocessing.Process(target=frame_extract_1)
frame_extractor_2 = multiprocessing.Process(target=frame_extract_2)
frame_extractor_3 = multiprocessing.Process(target=frame_extract_3)
frame_extractor_4 = multiprocessing.Process(target=frame_extract_4)
frame_extractor_1.start()
frame_extractor_2.start()
frame_extractor_3.start()
frame_extractor_4.start()
frame_extractor_1.join()
frame_extractor_2.join()
frame_extractor_3.join()
frame_extractor_4.join()
Do you know what I am doing wrong? Every "Processor" creates the full Video, without skipping 4 Frames and letting the other Processors do the remaining 3.

Recording video in specified time intervals and then saving them into file OpenCv Python

Here are my goals.
Capture video continuously until 'q; is pressed
Every ten seconds save the video in created directory file
Continue step two until 'q' is pressed
I am executing the following code. But when creating files it's creating 6kb files and saying cannot play. I am fairly new to opencv and python. Not sure what I am missing. Running this code on pycharm with Python 3.6. Also the
cv2.imshow('frame',frame)
stops after ten seconds but recording is happening in background and files are created.
import numpy as np
import cv2
import time
import os
import random
import sys
fps=24
width=864
height=640
video_codec=cv2.VideoWriter_fourcc('D','I','V','X')
name = random.randint(0,1000)
print (name)
if (os.path.isdir(str(name)) is False):
name = random.randint(0,1000)
name=str(name)
name = os.path.join(os.getcwd(), str(name))
print('ALl logs saved in dir:', name)
os.mkdir(name)
cap = cv2.VideoCapture(0)
ret=cap.set(3, 864)
ret=cap.set(4, 480)
cur_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
start=time.time()
video_file_count = 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
print('Capture video saved location : {}'.format(video_file))
while(cap.isOpened()):
start_time = time.time()
ret, frame = cap.read()
if ret==True:
cv2.imshow('frame',frame)
if (time.time() - start > 10):
start = time.time()
video_file_count += 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
video_writer = cv2.VideoWriter(video_file,video_codec, fps,(int(cap.get(3)),int(cap.get(4))))
time.sleep(10)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
I want files with the recorded videos. Files are generated but size 6kb and nothing is being recorded.
You're almost there! Given that I understood what your goal is, and with minimal change to your code, here is what worked for me.
This writes a new video file every ten seconds while recording each frame into the current video.
import numpy as np
import cv2
import time
import os
import random
import sys
fps = 24
width = 864
height = 640
video_codec = cv2.VideoWriter_fourcc("D", "I", "V", "X")
name = random.randint(0, 1000)
print(name)
if os.path.isdir(str(name)) is False:
name = random.randint(0, 1000)
name = str(name)
name = os.path.join(os.getcwd(), str(name))
print("ALl logs saved in dir:", name)
os.mkdir(name)
cap = cv2.VideoCapture(0)
ret = cap.set(3, 864)
ret = cap.set(4, 480)
cur_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
start = time.time()
video_file_count = 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
print("Capture video saved location : {}".format(video_file))
# Create a video write before entering the loop
video_writer = cv2.VideoWriter(
video_file, video_codec, fps, (int(cap.get(3)), int(cap.get(4)))
)
while cap.isOpened():
start_time = time.time()
ret, frame = cap.read()
if ret == True:
cv2.imshow("frame", frame)
if time.time() - start > 10:
start = time.time()
video_file_count += 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
video_writer = cv2.VideoWriter(
video_file, video_codec, fps, (int(cap.get(3)), int(cap.get(4)))
)
# No sleeping! We don't want to sleep, we want to write
# time.sleep(10)
# Write the frame to the current video writer
video_writer.write(frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
else:
break
cap.release()
cv2.destroyAllWindows()
A sign that the videos are being received at 6 kb, an error with the codec. You need to download opencv_ffmpeg.dll and place it in the Python3.2.1 folder and renamed to opencv_ffmpeg321.dll
This solved the problem for me, and before that, 5.6 kb videos were created, regardless of what I do. But the problem is deeper than it seems, it can still be connected with a mismatch in the resolution of the stream and the recording.
For OpenCV version X.Y.Z
opencv_ffmpeg.dll ==> opencv_ffmpegXYZ.dll
For 64-bit version of OpenCV X.Y.Z
opencv_ffmpeg.dll ==> opencv_ffmpegXYZ_64.dll

Categories