How to solve Opencv VideoWriter issues with global variables - python

I'mm writing this piece of python to display a stream of video from my webcam while at the same time record the video - which I've got working, however I've grayscaled the video streaming to my screen and time stamped it - but my recorded video is in colour! I've included the code below - I've tried using some global variables but nothing worked - any help, greatly appreciated
import cv2
import numpy as np
import time, datetime
import os
genericfilename = "recording"
filetime = str(time.time())
extension = '.avi'
filename = genericfilename + filetime +extension
frames_per_second = 100
res = '720p'
print("NEW FILE NAME: " + filename)
# Set resolution for the video capture
def change_res(cap, width, height):
cap.set(3, width)
cap.set(4, height)
# Standard Video Dimensions Sizes
STD_DIMENSIONS = {
"480p": (640, 480),
"720p": (1280, 720),
"1080p": (1920, 1080),
"4k": (3840, 2160),
}
# grab resolution dimensions and set video capture to it.
def get_dims(cap, res='1080p'):
width, height = STD_DIMENSIONS["480p"]
if res in STD_DIMENSIONS:
width,height = STD_DIMENSIONS[res]
## change the current caputre device
## to the resulting resolution
change_res(cap, width, height)
return width, height
# Video Encoding, might require additional installs
VIDEO_TYPE = {
'avi': cv2.VideoWriter_fourcc(*'XVID'),
#'mp4': cv2.VideoWriter_fourcc(*'H264'),
'mp4': cv2.VideoWriter_fourcc(*'XVID'),
}
def get_video_type(filename):
filename, ext = os.path.splitext(filename)
if ext in VIDEO_TYPE:
return VIDEO_TYPE[ext]
return VIDEO_TYPE['avi']
capture = cv2.VideoCapture(0)
out = cv2.VideoWriter(filename, get_video_type(filename), 60,
get_dims(capture, res))
while(True):
ret, frame = capture.read()
out.write(frame)
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
font = cv2.FONT_ITALIC = 1
cv2.putText(grayFrame, str(datetime.datetime.now()), (-330, 460), font, 3,
(200, 200, 200), 2, cv2.LINE_AA)
cv2.imshow('combilift output', grayFrame)
# Press Q on keyboard to exit
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if cv2.waitKey(1) & 0xFF == ord('r'):
print(datetime.datetime.now())
capture.release()
out.release()
cv2.destroyAllWindows()

You save the frame to video, then convert frame to gray.
out.write(frame)
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
If you want your recorded video to be gray, maybe reverse the order of operations and save grayFrame?
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out.write(grayFrame)
If you want to also save the texts, put the text before writing frame to output.

Lets take a look at ur code
out = cv2.VideoWriter(filename, get_video_type(filename), 60,
.....
while(True):
ret, frame = capture.read()
out.write(frame)
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
You first save out then convert color
The correct sequence should be
out = cv2.VideoWriter(filename, get_video_type(filename), 60,
.....
while(True):
ret, frame = capture.read()
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out.write(grayFrame)
I don't have data to test. Just in case you experience some issue with channels. You can use opencv merge(grayFrame,grayFrame,grayFrame) to create a normal 3 channel grey scale image and save to video

Related

How to make OpenCv on Python play video that is already played from web cam?

Essentially I need a loop inside of a loop, so the live-video could be played using another live-video as a reference. Is it, for example, possible to save video on hardware and then play it from there in real time? If yes, then how? I have a code with an attempt to meake something similar below. ORB detector shouldn`t affect the process.
import cv2
width = 640
height = 480
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while True:
frame_read = cap
(ret, myFrame) = cap.read()
img = cv2.resize(myFrame, (width, height))
orb = cv2.ORB_create()
kp = orb.detect(img, None)
(kp, des) = orb.compute(img, kp)
img2 = cv2.drawKeypoints(img, kp, img, color=(0xFF, 0, 0xFF))
img2 = cv2.flip(img2, 0)
out.write(img2)
cv2.imshow('test', img2)
while True:
test = cap.open('output.avi')
frame_read = test
(ret, kpFrame) = test.read()
img3 = cv2.resize(kpFrame, (width, height))
cv2.imshow('test2', img3)
if cv2.waitKey(1) & 0xFF == ord('q'):
break

failing to play the whole video using cv2

i am trying to play a video using cv2 but it's only showing one frame and the video disappears
import cv2
img_file = 'car image.jpg'
video = cv2.VideoCapture('Tesla Dashcam AccidentTrim.mp4')
while True:
(read_successful, frame) = video.read()
if read_successful:
grayscaled_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
else:
break
classifier_file = 'car_detector.xml'
#Display the image with the faces spotted
cv2.imshow('Newton Caffrey Face Detector', grayscaled_frame)
#Don't Autoclose here (wait here in the code and listen for a key press)
cv2.waitKey(1)
I used the following code for displaying the video using cv2. It will keep displaying frames untill video ends. hope this will work for you, peace!
import cv2
cap = cv2.VideoCapture("Video.mp4")
width = 400
height = 300
num = 0
while True:
ret, frame = cap.read()
if ret:
frame = cv2.resize (frame, (width, height))
cv2.imshow("frame", frame)
if cv2.waitKey(1) & 0xff == ord('q'):
break
cv2.destroyAllWindows()

OpenCV ret=False, is it reading the video, or not?

I want to detect edges of a video file (640x640 9sn.) and save the result. I followed OpenCV documents and some other examples. Most of the examples that I found was reading from camera.
Here is my code. I checked cap.isOpened(), it returns True but ret does False and frame is NoneType object. What is confusing is that I'm having the gray array which depends the condition if ret == True. How can I get gray matrix if ret = False?
(I installed ffmpeg pip install ffmpeg-python)
(andy.avi was saved in folder but it's broke, empty)
import cv2
import numpy as np
cap = cv2.VideoCapture("...\\video.mp4")
while(cap.isOpened()):
ret, frame = cap.read()
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
size = (frame_width, frame_height)
result = cv2.VideoWriter('andy.avi',
cv2.VideoWriter_fourcc(*'DIVX'),
30, size)
if ret == True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 45, 90)
result.write(edges)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
result.release()
cv2.destroyAllWindows()
your code should be changed like this
# importing the module
import cv2
import numpy as np
# reading the vedio
source = cv2.VideoCapture("...\\video.mp4")
# We need to set resolutions.
# so, convert them from float to integer.
frame_width = int(source.get(3))
frame_height = int(source.get(4))
size = (frame_width, frame_height)
result = cv2.VideoWriter('andy.avi',
cv2.VideoWriter_fourcc(*'DIVX'),
30, size, 0)
# running the loop
while True:
# extracting the frames
ret, img = source.read()
# converting to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 45, 90)
# write to gray-scale
result.write(edges)
# displaying the video
cv2.imshow("Live", gray)
# exiting the loop
key = cv2.waitKey(1)
if key == ord("q"):
break
# closing the window
result.release()
source.release()
cv2.destroyAllWindows()
If helpful this for you give 👍

Save the edge detected frames from a video as a video (opencv)

I Want to save the edge detected frames as a video. I am able to preview the frames of the video but the output video doesn't play.
cap = cv2.VideoCapture("video.mp4")
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mp4', fourcc, 23.976, (1280,720))
while(cap.isOpened()):
ret, frame = cap.read()
edges = cv.Canny(frame,50,50)
out.write(edges)
cv2.imshow('frame', edges)
c = cv2.waitKey(1)
if c & 0xFF == ord('q'):
break
cap.release()
out.release()
There are three issues I would like to address.
You are applying Canny to each video frame. What is the output size:
print(edges.shape)
(720, 1280)
The dimension 720, 1280 means the frame is a gray-scale value. If the frame is a color image then the dimension will be (720, 1080, 3) for each channel R, G, B.
Therefore you need to initialize your VideoWriter object as a grey-scale images.
out = cv2.VideoWriter('output.mp4', fourcc, 23.976, (1280,720), isColor=False)
Make sure you are capturing the next frame:
ret, frame = cap.read()
if ret:
edges = cv.Canny(frame,50,50)
.
.
Make sure your frame are the same dimension with the VideoWriter object
while cap.isOpened():
ret, frame = cap.read()
if ret:
edges = cv2.Canny(frame, 50, 50)
edges = cv2.resize(edges, (1280, 720))
out.write(edges)
.
.
Code:
import cv2
cap = cv2.VideoCapture("video.mp4")
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
out = cv2.VideoWriter('output.mp4', fourcc, 23.976, (1280, 720), isColor=False)
while cap.isOpened():
ret, frame = cap.read()
if ret:
edges = cv2.Canny(frame, 50, 50)
edges = cv2.resize(edges, (1280, 720))
out.write(edges)
cv2.imshow('frame', edges)
c = cv2.waitKey(1)
if c & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()

Save capture part of screen using mss to video using opencv2 in python

I want to save part of screen as video. When running code below I can see the window and fps count on it (around 100-140 fps).
Code (installed mss and opencv2 are required):
import numpy as np
import cv2
import time
import mss
frame_width = 1280
frame_height = 720
frame_rate = 20.0
PATH_TO_MIDDLE = "output.avi"
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter(PATH_TO_MIDDLE, fourcc, frame_rate,
(frame_width, frame_height))
with mss.mss() as sct:
# Part of the screen to capture
monitor = {"top": 120, "left": 280, "width": 1368, "height": 770}
while "Screen capturing":
last_time = time.time()
# Get raw pixels from the screen, save it to a Numpy array
img = np.array(sct.grab(monitor))
img = cv2.resize(img, (1280, 720))
frame = img
cv2.putText(frame, "FPS: %f" % (1.0 / (time.time() - last_time)),
(10, 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
out.write(frame)
cv2.imshow('frame', frame)
# Press "q" to quit
if cv2.waitKey(25) & 0xFF == ord("q"):
break
# Clean up
out.release()
cv2.destroyAllWindows()
This code not produced any errors, so I don't understand what's wrong here. Output file output.avi created fine, but with size 5,7 KB (and this file I didn't open). I tried change VideoWriter, move out and fourcc inside the while - but didn't succeed. Also tried to change frame_rate and set frame width and height to more smaller values. Also looked at this question, but cannot succeed.
Added those two lines after frame = img helps:
frame = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
Maybe opencv can't save image as np.array so here need additional usage of cv2.cvtColor.

Categories