I am using openCv for making video processing. What I do is reading a video frame by frame, then applying some processing on each frame and then displaying the new modified frame. My code looks like that :
video_capture = cv2.VideoCapture('video.mp4')
while True:
# Capture frame-by-frame
ret, frame = video_capture.read()
# Applying some processing to frame
.
.
.
# Displaying the new frame with processing
img=cv2.imshow('title', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
This way I can display instantaneously the processed video. The problem is the display is lagging much due to the presence of the 'waitkey'. Is there another way for display images in real time to form a video, but with another module than cv2?
Thank you
One option is Tkinter, you can find some information here. Along with Tkinter, it uses python-gstreamer and python-gobject. It is much more complicated to set up, however it allows for more customization options.
Related
I have coded the face expression detection using Jupyter notebook, detecting seven expressions of the face (Anger, Sad, Disgust, Happy, ...) and tried the real-time detection using the camera of my laptop. Now I want to record those expressions detected by the model in the real-time detection and create a figure of the detected expressions over time. First of all, is it possible to do so? If not, what other options do I have? For example, can I record the video taken by the camera and later detect the expressions from the video and make a figure from all the expressions detected over time? Thank you all for helping me!
You could do something like this:
from tensorflow import keras
import cv2
all_labels = ["Anger", "Sad", "Disgust", "Happy"]
# load the trained model, or train a model
model = keras.models.load_model('path/to/location')
# Open the camera
cap = cv2.VideoCapture(0)
# Or similarly open a saved video
cap = cv2.VideoCapture('path/to/video')
# Check if camera was opened correctly
if not (cap.isOpened()):
print("Could not open video device")
# Fetch one frame at a time from your camera in real-time or from the video
i=0
while(True):
# frame is a numpy array, that you can predict on
ret, frame = cap.read()
# Obtain the prediction (you may have to reshape frame according to your model)
prediction = model(frame, training=False)
# obtain a label from prediction, depending on your label list
# saving the frame in a different folder depending on label predicted
if label in all_labels:
cv2.imwrite('{}/frame_{}.jpg'.format(label, i), frame)
i = i+1
#Waits for a user input to quit the application
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
cap.release()
cv2.destroyAllWindows()
I made an answer to a similar but not identical problem. Maybe you can draw inspiration from that. Also this is a great tutorial for capturing live videos made by OpenCV.
I am writing a basic program to read video frame from a video file and display it on screen using OpenCV functions. I was able to do that. But when I ran the same file after few days, I was unable to capture the frames using VideoCapture Function in OpenCV.
But reading frames from webcam still works. But I am unable to read frames from a video file
cap = cv2.VideoCapture('video1.mp4')
# print(cap.isOpened()) Just for debugging purpose, it prints false
while cap.isOpened():
ret, frame = cap.read()
cv2.imshow('Title', frame)
if cv2.waitKey(10) & 0xFF==ord('q'):# or frame_count > 25:
break
cap.release()
cv2.destroyAllWindows()
The above snippet is the one I wrote. What might be the possible reason for it to work properly initially, but now failing to do so?
I'm working on a project that will eventually have to process webcam images in real-time. I have some suitable test videos that I use to test my program. However, I don't know how to simulate real-time processing with a video file. I can read in each frame and process it, but this is not realistic since the algorithm is too heavy to run on every frame. I would like to 'stream' the video separately and pull in a frame each time the algorithm starts to test with a realistic fps, but I don't know how to do this.
Here is the basic layout of the code you can use :
import cv2
cap = cv2.VideoCapture('path to video file')
while cap.isOpened():
ret,frame = cap.read()
### YOUR CODE HERE ###
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows() # destroy all opened windows
I have a python code which is opening a live web cam and I can the video feed. Below is the code:
import cv2
vcap = cv2.VideoCapture(1)
while(1):
ret, frame = vcap.read()
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
vcap.release()
cv2.destroyAllWindows()
The window which appears and show the live webcam video is quite small. But if I play a videofile using the above code, the window which appears is quite big in size. In above code I am not mentioning anything to resize the window.
Why is this difference.?
How can I make the videofile window size a bit smaller.?
The difference is at the origin size of the images. That is saying that the image obtained by the camera is smaller than that from video file.
To make the window size smaller, you can resize the image obtained from video. The code is:
ret, frame = vcap.read()
frame = cv2.resize(frame, None, None, fx=0.5, fy=0.5)
For more details, you can refer to resize
===Additional Docs===
The function imshow displays an image in the specified window. If the window was created with the cv::WINDOW_AUTOSIZE flag, the image is shown with its original size, however it is still limited by the screen resolution. Otherwise, the image is scaled to fit the window.
If the window was not created before this function, as you did, it is assumed creating a window with cv::WINDOW_AUTOSIZE.
You can refer to imshow for more details.
As you can see from the documentation here, the first argument to imshow() is window a name. If you don't explicitly create a window with that name prior to calling imshow(), OpenCV will create a window with the CV_WINDOW_AUTOSIZE flag set, which means it will show frame with its original size. So if you have different frames, the window size will also be different. To get windows smaller what you can do it, create a window with WINDOW_NORMAL flag set, which allows you to set your window size. So you can do something like this:
cv2.namedWindow("Window", cv2.WINDOW_NORMAL)
# set your desired size
cv2.resizeWindow('Window', width, height)
cv2.imshow('Window', frame)
I have written a basic code which captures an image from webcam using OpenCV & Python 2.7.
The code is as follows:
import numpy
import cv2
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
cv2.imshow('image',frame)
cap.release()
cv2.waitKey(0)
cv2.destroyAllWindows()
This code gives the correct output but my camera takes a few seconds to focus so I get a black or dim image as output instead of a bright proper focused image..
How can I solve this problem in a more mature way?
You need an "auto capture" algorithm. Auto capturing algorithms are various depending on what your case is. For example if you need take a shoot for a document that you want to OCR it later, you have to check how much this text is OCRable in order to take the image. However, in the general case there is something called Reference-less Image Quality Assurance that will help you to rate how much this image is good. Then, if it is good enough, take a shoot. However, implementing it is not an easy task.
If you need something fast and easy, just compute the sharpness of the image and depend on it to take the photo or not. See this :http://answers.opencv.org/question/5395/how-to-calculate-blurriness-and-sharpness-of-a-given-image/
Another option could be using a face detector if you are taking photos for humans. OpenCV has a cascade classifier with pre-trained model for human face. Just try to detect it and when it is detected, take the shoot.
You may also combine the last two types together in a hybrid mode. In other words, Detect the face then make sure it is sharp enough then take the photo
You could wait till the video capturing has been initialized by modifying the code as:
import cv2
cv2.namedWindow("output")
cap = cv2.VideoCapture(0)
if cap.isOpened(): # Getting the first frame
ret, frame = cap.read()
else:
ret = False
while ret:
cv2.imshow("output", frame)
ret, frame = cap.read()
key = cv2.waitKey(20)
if key == 27: # exit on Escape key
break
cv2.destroyWindow("output")