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

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

Related

How to display an image and a terminal in OpenCV

How can use OpenCV to display my webcam and a terminal at the same time? I need the terminal to run some commands to make the webcam appear and others different actions with the object detection.
Here's a very simple example of running a webcam while at the same time being able to use terminal input() by doing all the opencv frame capturing, and imshowing from a separate thread:
from threading import Thread
import cv2
shouldExit = False
color = True
def cam():
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
while not shouldExit:
ret, frame = cap.read()
if not color:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow("window title", frame)
cv2.waitKey(1)
cap.release()
cv2.destroyAllWindows()
t = Thread(target=cam)
t.start()
while True:
print('select an action: q-quit, t-toggle color')
choice = input(">").strip().lower()
if choice == 'q':
shouldExit = True
t.join()
break
elif choice == 't':
color = not color
else:
print('invalid input')

How to play it on fullscreen python cv2

How do I play the video.mp4 in fullscreen instead of playing it in a window
and is there any way to play video with audio without playing the audio separately?
import cv2
from playsound import playsound
from threading import Thread
def func1():
cap = cv2.VideoCapture("video.mp4")
ret, frame = cap.read()
while(1):
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(33) & 0xFF == ord('q') or ret==False :
cap.release()
cv2.destroyAllWindows()
break
cv2.imshow('frame',frame)
def func2():
playsound('6989946141014084358.mp3')
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).start()
You should be able to setup the window ahead of time (e.g. before your blocking while loop):
cv2.namedWindow('frame',cv2.WINDOW_NORMAL)
cv2.setWindowProperty('frame',cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)

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)

create new window video stream in tkinter

In my program, i want to show the camera stream and gui in apart. I think i have to use thread for this in python but i dont know how to do that?
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
How can i change above code to open a new window and display the video stream with thread.
I hope I understand you correctly, that you want to run:
the capturing of the images from the camera in one thread,
while in parallel show the captured images (when available) in another thread.
A classic "producer-consumer problem"!
Consider then the following code:
import cv2
import threading
from threading import Event
class multi_thread_stream:
def __init__(self, ready=None):
self.ready = ready
self.cap = cv2.VideoCapture(0)
self.frame = {}
#Create the Threads
self.t1 = threading.Thread(target=self.capture_stream)
self.t2 = threading.Thread(target=self.display_image)
self.t1.name = 'capture_thread'
self.t2.name = 'display_thread'
self.t1.start()
self.t2.start()
def capture_stream(self):
while True:
# Capture frame-by-frame
self.ret, self.frame = self.cap.read()
self.ready.set()
if cv2.waitKey(1) & 0xFF == ord('q'):
break
def display_image(self):
while True:
# Display the resulting frame
self.ready.wait()
cv2.imshow('frame_2nd_trhead', self.frame)
self.ready.clear()
if cv2.waitKey(1) & 0xFF == ord('q'):
break;
def __del__(self):
# When everything done, release the capture
self.cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
ready = Event()
mts = multi_thread_stream(ready)
mts.t1.join()
mts.t2.join()
There are two functions, that run in two threads. The display-thread waits for a trigger and until the capture-thread has already read a frame and sent a trigger to the display-thread, the display-thread cannot continue further and hence cannot show an image (or throw an error of invalid variable size).
Hope it helps. (or at least it can be a basis for your further solution).

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()

Categories