Save image stream with timestamp using OpenCV Python - python

I am using open CV, Python to save same camera Images in jpg and png format.
I am using timestamp to save the images in sequence. My code sample is following. But the problem is it only saves one image every time I execute. What will be the best solution to save the image stream with timestamp
import numpy as np
import cv2
import time
camera = cv2.VideoCapture(0)
time = time.time() #timestamp
def saveJpgImage(frame):
#process image
img_name = "opencv_frame_{}.jpg".format(time)
cv2.imwrite(img_name, frame)
def savePngImage():
#process image
img_name = "opencv_frame_{}.png".format(time)
cv2.imwrite(img_name, frame)
def main():
while True:
ret, frame = cam.read()
cv2.imshow("Camera Images", frame)
if not ret:
break
k = cv2.waitKey(1)
if k%256 == 27:
# ESC pressed
print("Escape hit, closing...")
break
elif k%256 == 32:
saveJpgImage(frame)
savePngImage(frame)
if __name__ == '__main__':
main()

You're testing when a key is pressed and calling the save function when it's pressed. If you want to call a video loop when the key is pressed please do so! (don't forget to include the escape method!)

Related

Computer Terminating OpenCv Image Grabber Program

I Have Created a Program in Python in which it uses opencv to grab some images and save it.I have runned this program on my mac and it works fine does what i expect but on my computer the webcam feed shows and the first image when i click space works but when i click for the second time to grab images it doesnt works.The following is the error message that it shows
[ WARN:0] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-hfoi92lm\opencv\modules\videoio\src\cap_msmf.cpp (435) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
Below is my code
import cv2
import subprocess
from sys import exit
import os
# Code!
import time
cam = cv2.VideoCapture(0)
cv2.namedWindow("test")
cv2.startWindowThread()
img_counter = 0
while True:
ret, frame = cam.read()
if not ret:
print("failed to grab frame")
break
cv2.imshow("test", frame)
k = cv2.waitKey(1)
if k%256 == 27:
# ESC pressed
print("Escape hit, closing...")
break
elif k%256 == 32:
# SPACE pressed
img_name = f'\\Users\\Anush\\PycharmProjects\\PelletInspection\\Sample_Images\\Sample_Image_{img_counter}.jpg'
cv2.imwrite(img_name, frame)
print("{} written!".format(img_name))
img_counter += 1
cam.release()
cv2.destroyAllWindows()
try to comment #cv2.startWindowThread()
try editing cv2.waitKey(33) instead of cv2.waitKey(1)

uninterrupted while loop with python cv2.VideoCapture() and string input

I use this code to capture and display the input from my webcam.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
check, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
I have a barcode scanner and want to check inside the while loop if a specific string gets scanned in.
input() interupts the stream from the webcam. I need something like cv2.waitKey() but for strings
while(True):
check, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitString(barcode) == '123456':
# do something
if cv2.waitString(barcode) == '098765':
# do something else
I tried msvcrt, but to no avail. The stream continues but nothing gets printed.
if msvcrt.kbhit():
if msvcrt.getwche() == '280602017300':
print("Barcode scanned!")
Or is there a way to skip input() until something was entered?
UPDATE
Making some progress with the help of this post.
How to read keyboard-input?
I was able to update my code.
import threading
import queue
import time
import numpy as np
import cv2
def read_kbd_input(inputQueue):
print('Ready for keyboard input:')
while (True):
input_str = input()
inputQueue.put(input_str)
def main():
inputQueue = queue.Queue()
inputThread = threading.Thread(target=read_kbd_input, args=(inputQueue,), daemon=True)
inputThread.start()
cap = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_DUPLEX
fontScale = 1
fontColor = (255,255,255)
lineType = 2
input_str = "test"
while (True):
check, frame = cap.read()
if (inputQueue.qsize() > 0):
input_str = inputQueue.get()
if (input_str == '280602017300'):
print("do something")
cv2.putText(frame, input_str, (10,30), font, fontScale, fontColor, lineType)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
time.sleep(0.01)
print("End.")
if (__name__ == '__main__'):
main()
Now the only problem left is that my webcam stream is supposed to run in fullscreen. So the console will allways be in the background and therefore wont get the inputs form the keyboard or my barcode scanner.
need it the other way around

OpenCV Video capture using keyboard to start/stop

I have a running script capable of starting/stopping a video stream using 2 different keys;
Program runs and shows the live stream.
When ESC is hit, the program exits.
When SPACE is hit, the video stream is captured.
However, when a video is captured it stores all the stream from the beginning of script execution.
import cv2
import numpy as np
capture = cv2.VideoCapture(1)
codec = cv2.VideoWriter_fourcc(*'XVID')
output = cv2.VideoWriter('CAPTURE.avi', codec, 30, (640, 480))
while True:
ret, frame_temp = capture.read()
cv2.imshow('FRAME', frame_temp)
key=cv2.waitKey(1)
if key%256 == 27:
break
elif key%256 == 32:
output.write(frame_temp)
capture.release()
output.release()
cv2.destroyAllWindows()
So, instead when the program runs I would like;
Program runs and shows the live stream.
Begin recording the stream when SPACE is hit and stop the recording when SPACE is hit once more.
Any suggestions would be much appreciated.
You need an extra variable to figure out if you are recording. I made a variable called recording_flag
import cv2
import numpy as np
capture = cv2.VideoCapture(1)
codec = cv2.VideoWriter_fourcc(*'XVID')
recording_flag = False
while True:
ret, frame_temp = capture.read()
cv2.imshow('FRAME', frame_temp)
key=cv2.waitKey(1)
if key%256 == 27:
break
elif key%256 == 32:
if recording_flag == False:
# we are transitioning from not recording to recording
output = cv2.VideoWriter('CAPTURE.avi', codec, 30, (640, 480))
recording_flag = True
else:
# transitioning from recording to not recording
recording_flag = False
if recording_flag:
output.write(frame_temp)
capture.release()
output.release()
cv2.destroyAllWindows()
This line while True: isn't exactly ideal for what you're trying to do. I would recommend you define a function to do the recording and have it recursively call itself if the user stops recording via the space key. The top of your script would still start the same:
import cv2
import numpy as np
capture = cv2.VideoCapture(1)
codec = cv2.VideoWriter_fourcc(*'XVID')
output = cv2.VideoWriter('CAPTURE.avi', codec, 30, (640, 480))
Next you would define your function, it starts by waiting (forever) for a key to be pressed. Once a key is pressed if it is escape (27) it exits the function and cleans up, if it is space (32) it sets a boolean flag that starts recording (while loop). If neither escape or space is pressed it calls itself and starts the process over. Inside the while loop it checks if a key is pressed if so it checks if it is escape (27) or space (32). If either it hit it either exits the function (escape) or haults recording by calling itself which starts the process all over again (space).
def wait_then_capture():
key = cv2.waitKey(0)
if key%256 == 27:
return
elif key%256 == 32:
record = True
else:
wait_then_capture()
while record == True:
ret, frame_temp = capture.read()
cv2.imshow('FRAME', frame_temp)
key = cv2.waitKey(1)
if key%256 == 27:
return
elif key%256 == 32:
break
output.write(frame)
wait_then_capture()
We then call our new function and end the script with the same cleanup you already have
wait_then_capture()
capture.release()
output.release()
cv2.destroyAllWindows()
Your finished script would look like this
import cv2
import numpy as np
capture = cv2.VideoCapture(1)
codec = cv2.VideoWriter_fourcc(*'XVID')
output = cv2.VideoWriter('CAPTURE.avi', codec, 30, (640, 480))
def wait_then_capture():
key = cv2.waitKey(0)
if key%256 == 27:
return
elif key%256 == 32:
record = True
else:
wait_then_capture()
while record == True:
ret, frame_temp = capture.read()
cv2.imshow('FRAME', frame_temp)
key = cv2.waitKey(1)
if key%256 == 27:
return
elif key%256 == 32:
break
output.write(frame)
wait_then_capture()
wait_then_capture()
capture.release()
output.release()
cv2.destroyAllWindows()

How to capture video and save from webcam on click or pressing any key from keyboard using OpenCV

I want to capture and save a video from my webcam in a way that when I press any key (enter, space etc) from keyboard then code should start save the video from current frame and when I press same key from keyboard then code should stop to save the video. This is my code currently:
import cv2
cap = cv2.VideoCapture(0)
if (cap.isOpened() == False):
print("Unable to read camera feed")
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
out = cv2.VideoWriter('output.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))
while(True):
ret, frame = cap.read()
k = cv2.waitKey(1)
if ret == True:
cv2.imshow('frame',frame)
# press space key to start recording
if k%256 == 32:
out.write(frame)
# press q key to close the program
elif k & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
My current code is capturing only one (current frame) when I press space key. I need help to solve this problem.
Here is the same question but it is for images, it can't solve for videos.
Also is there a better way to capture and save video which can solve my problem?
The problem is that the code you wrote only calls the function out.write(frame) when you press the space key.
This should solve the issue:
create some sentinel variable at the beginning of your code. let's say record = False
And then inside your loop, make this change:
if k%256 == 32:
record = True
if record:
out.write(frame)
So this is how your code will look like:
import cv2
record = False
cap = cv2.VideoCapture(0)
if (cap.isOpened() == False):
print("Unable to read camera feed")
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
out = cv2.VideoWriter('output.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))
while(True):
ret, frame = cap.read()
k = cv2.waitKey(1)
if ret == True:
cv2.imshow('frame',frame)
# press space key to start recording
if k%256 == 32:
record = True
if record:
out.write(frame)
# press q key to close the program
if k & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()

Cannot Close Video Window in OpenCV

I would like to play a video in openCV using python and close that window at any time, but it is not working.
import numpy as np
import cv2
fileName='test.mp4' # change the file name if needed
cap = cv2.VideoCapture(fileName) # load the video
while(cap.isOpened()):
# play the video by reading frame by frame
ret, frame = cap.read()
if ret==True:
# optional: do some image processing here
cv2.imshow('frame',frame) # show the video
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cv2.waitKey(1)
cv2.destroyAllWindows()
cv2.waitKey(1)
The window opens and starts playing the video, but I cannot close the window.
You can use cv2.getWindowProperty('window-name', index) to detect if the window is closed. I'm not totally sure about the index but this worked for me:
import cv2
filename = 'test.mp4'
cam = cv2.VideoCapture(filename)
while True:
ret, frame = cam.read()
if not ret:
break
cv2.imshow('asd', frame)
cv2.waitKey(1)
if cv2.getWindowProperty('asd', 4) < 1:
break

Categories