Python OpenCV - Update camera index of live webcam view - python

I am viewing a webcam camera live feed. I would like to incorporate this into a Tkinter GUI and have a dropdown selection that allows one to change the camera index, and therefore the webcam being used, on the fly.
How can this be achieved?
Example code:
import cv2
def show_webcam(mirror=False):
cam = cv2.VideoCapture(0)
while True:
ret_val, img = cam.read()
if mirror:
img = cv2.flip(img, 1)
cv2.imshow('my webcam', img)
if cv2.waitKey(1) == 27:
break # esc to quit
cv2.destroyAllWindows()
def main():
show_webcam(mirror=True)
if __name__ == '__main__':
main()

To change camera at run time all you need to change is the index you pass in
cv2.VideoCapture(index).
Find out how many camera you will be using for your app and for 3 cameras, you can change it through changing index to 0 or 1 or 2.
Add one more parameter as index
show_webcam(mirror=True, index)
in function side you can use this
def show_webcam(mirror=False,index):
cam = cv2.VideoCapture(index)
while True:
ret_val, img = cam.read()
if mirror:
img = cv2.flip(img, 1)
cv2.imshow('my webcam', img)
if cv2.waitKey(1) == 27:
break # esc to quit
cv2.destroyAllWindows()

Related

How do I add an image overlay to my live video using cv2?

This is my code, I've looked at some tutorials but can't find what I'm looking for
I want to overlay the Frame.png image on my webcam. I tried to add the image directly but it didn't work either. If possible, Is there a way to add an image, not to overlay but to keep the image at a certain coordinate in the live webcam window
import cv2
import numpy as np
def detect_and_save():
alpha = 0.2
beta = 1-alpha
cap = cv2.VideoCapture(0)
sciframe = cv2.imread('Frame.png')
classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
while True:
ret ,frame = cap.read()
overlay = frame.copy()
output = frame.copy()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = classifier.detectMultiScale(gray,1.5,5)
cv2.putText(output, "HUD Test",(175, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 50, 50), 3)
cv2
for face in faces:
x,y,w,h = face
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,200,0),-1)
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,0,0),1)
cv2.rectangle(overlay,(x,y-20),(x+w,y),(25,20,0),-1)
cv2.addWeighted(overlay,alpha,output,beta,0,output)
cv2.putText(output,"Human",(x+10,y-10),cv2.FONT_HERSHEY_SIMPLEX,
0.35, (0, 0, 255), 1)
if not ret:
continue
cv2.imshow("HUD",output)
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('s'):
cv2.imwrite('./images/CID_{}.png'.format(time.strftime('%d%m%y_%H_%M_%S')),output)
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
import time
detect_and_save()
You can directly add one image on top of another one at any coordinate easily in opencv.
cap = cv2.VideoCapture(0)
im_height = 50 #define your top image size here
im_width = 50
im = cv2.resize(cv2.imread("Frame.png"), (im_width, im_height))
while (True):
ret, frame = cap.read()
frame[0:im_width, 0:im_height] = im #for top-left corner, 0:50 and 0:50 for my image; select your region here like 200:250
cv2.imshow("live camera", frame)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()

Error using cv2 to train the camera (Python)

I am trying to train my camera using cv2 library. I am using a camera connected to Raspberry Pi3. it works fine since i tested the camera. However whenever I try to using the camera for face recognition later I keep getting this error:
return compile(source, filename, mode, PyCF_ONLY_AST)
IndentationError: expected an indented block
this is the code below:
import cv2
name = 'Mohammed' #replace with your name
cam = cv2.VideoCapture(0)
cv2.namedWindow("press space to take a photo", cv2.WINDOW_NORMAL)
cv2.resizeWindow("press space to take a photo", 500, 300)
img_counter = 0
while True:
ret, frame = cam.read()
if not ret:
print("failed to grab frame")
break
cv2.imshow("press space to take a photo", frame)
k = cv2.waitKey(1)
if k%256 == 27:
# ESC pressed
print("Escape hit, closing…")
break
elif k%256 == 32:
# SPACE pressed
img_name = "dataset/"+ name +"/image_{}.jpg".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_name))
img_counter += 1
cam.release()
cv2.destroyAllWindows()

OpenCV input delay in capturing frames

I have written a code to enable capturing images from webcam feed using OpenCV. However there is an input delay whenever I press the key to capture my frame. There is no delay when I use it to quit, but there a significant delay when I use capture. I measured this by printing a statement inside both the cases, on pressing c the statement takes a delay before printing. The problem seems to me something like...the camera resources are being used and not freed up in time for the next key press or something like that....but not sure.
import cv2 as cv
import numpy as np
import glob
import matplotlib.pyplot as plt
cap = cv.VideoCapture(1)
img_counter = 0
while True:
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# cv.imshow('frame',frame)
cv.imshow('gray', gray)
if not ret:
break
if cv.waitKey(1) & 0xFF == ord('q'):
print('helloq')
break
elif cv.waitKey(1) & 0xFF == ord('c'):
print('hello{}'.format(img_counter))
img_name = "opencv_frame_{}.png".format(img_counter)
cv.imwrite(img_name, gray)
img_counter += 1
I am using an external web camera and
cv2.__version__ = 3.4.2`
Solved your issue, it seems like its caused by your key check.
You should not call waitKey(1) more than once. It causes lag.
Try this solution:
cap = cv.VideoCapture(0)
img_counter = 0
while True:
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# cv.imshow('frame',frame)
cv.imshow('gray', gray)
if not ret:
break
key = cv.waitKey(1)
if key==ord('c'):
print('img{}'.format(img_counter))
img_name = "opencv_frame_{}.png".format(img_counter)
cv.imwrite(img_name, gray)
img_counter += 1
print("Succesfully saved!")
if key==ord('q'):
print('Closing cam...')
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()

OpenCV Python: Restarting a video

I am new to both OpenCV and Python, and I am trying to create a simple program that will read in a video file named 'SixtyFPS.mov' and replay the video when it has reached its end. Ideally I would like to have the video loop continuously. I have not been able to find a solution for this online, however most of the answers I see involve using cap.set(cv2.CAP_PROP_POS_FRAMES, 1) or something of that nature in order to reset the frames. If anyone can explain to me how to use the cap.set feature in order to restart the video that would be greatly appreciated.
# The video 'SixtyFPS.mov' was recorded on an iPhone 7 at 60 FPS
# The video has a length of roughly 4 seconds long and so the total number
# of frames should be ~240, however my number_of_frames variable is equal to 115
# I am looking for a way to restart the video once it has reached its end but
# I have not yet discovered a good method for doing so. Any advice would be
# greatly appreciated. I am using Python 3.6.4 and OpenCV 3.3.1
# I needed to rotate the video so that it would be viewed in portrait
# orientation rather than landscape
import cv2
import numpy as np
# Load in the video
video_cap = cv2.VideoCapture('SixtyFPS.mov')
# display the total number of frames. Should be ~240 and not 115
number_of_frames = int(video_cap.get(cv2.CAP_PROP_FRAME_COUNT))
print("The total number of frames is: " + str(number_of_frames))
# Check if video opened successfully
if (video_cap.isOpened() == False):
print("Error opening video file")
frame_counter = 0
# Read until video is completed
while(video_cap.isOpened()):
# Capture frame-by-frame
ret, frame = video_cap.read()
if ret == True:
frame_counter += 1
# resize the window
resized_vid = cv2.resize(frame, (720, 1280))
# Convert the video to grayscale
grayscale_vid = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Change the orientation from landscape to portrait by rotating
(h, w) = grayscale_vid.shape[:2]
center = (w / 2, h / 2)
M = cv2.getRotationMatrix2D(center, 270, 1.0)
rotated_video = cv2.warpAffine(grayscale_vid, M, (w, h))
# Display the rotated video
cv2.imshow('Pitch', rotated_video)
# trying to restart the video when the frame_counter
# reaches its maximum value of 110
if frame_counter >= 110:
# here is where I think I need to restart the video
# by setting the current frame to zero
# Press Q on keyboard to exit
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Break the loop
else:
break
# When everything done, release the video capture object
video_cap.release()
# Closes all the frames
cv2.destroyAllWindows()
It's been a while since this question has been posted, but just in case someone stumbled upon this answer, this code snippet with cap.set() worked for me. I relied on the documentation that can be found here (cpp) and here (python).
import cv2
# Get video handle.
cap = cv2.VideoCapture("path/to/video")
if not cap.isOpened():
print("Cannot initialize cap.")
exit()
# Get length of the video.
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# Initialize count.
count = 0
# Frames loop.
while True:
# Check length of the video.
if count == video_length:
# Reset to the first frame. Returns bool.
_ = cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
count = 0
# Get the frame.
success, image = cap.read()
if not success:
print("Cannot read frame.")
break
# do something with the image.
cv2.imshow("Frame", image)
# Quit by pressing 'q'.
if cv2.waitKey(1) & 0xFF == ord('q'):
break
count += 1
# Post loop.
cap.release()
cv2.destroyAllWindows()
I used the above to go some n number of frames back by combining cap.get() and cap.set().
This is a general way how the video can be resized to 480 x 800 (height x width) and made to loop.
import cv2
# Change this path to your video location
path = "path_to_your_video"
cap = cv2.VideoCapture(path)
while True:
ret, img = cap.read()
if not ret:
cap = cv2.VideoCapture(path)
ret, img = cap.read()
img = cv2.resize(img, (800, 480))
cv2.imshow("Video", img)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()

How to capture a picture in opencv

python newbie here I have following code which I'm using to capture a picture using opencv. It captures the picture when I press q key on keyboard.
Working fine so far.
import cv2
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
cv2.imshow('frame', rgb)
if cv2.waitKey(1) & 0xFF == ord('q'):
out = cv2.imwrite('capture.jpg', frame)
break
cap.release()
cv2.destroyAllWindows()
I need it to capture the picture when I give a command (like 'Capture now'). Can anyone help me how to capture a frame when user gives the written command rather than by pressing the key. Thanks
You can write like
reqCommand = 'Capture_pic'
command = input('Enter command')
if command == reqCommand:
out = cv2.imwrite('capture.jpg', frame)
Update:
This update is to make it enable to not block the execution of the program
import cv2
import threading
command = None
def process():
while True:
command = input('Enter command')
thread = threading.Thread(target=process)
thread.start()
cap = cv2.VideoCapture(0)
reqCommand = 'Capture_pic'
while(True):
ret, frame = cap.read()
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
cv2.imshow('frame', rgb)
if command == reqCommand:
out = cv2.imwrite('capture.jpg', frame)
thread.terminate()
break
cap.release()
cv2.destroyAllWindows()

Categories

Resources