How to send a default parameter in method (Python) - python

This is the class:
import pyautogui
import cv2
import numpy as np
class VidRec:
def screen(self,fps=12.0,time=10):
SCREEN_SIZE = tuple(pyautogui.size())
fourcc = cv2.VideoWriter_fourcc(*"XVID")
out = cv2.VideoWriter("output.avi", fourcc, self.fps, (SCREEN_SIZE))
for i in range(int(self.time * self.fps)):
img = pyautogui.screenshot()
# convert these pixels to a proper numpy array to work with OpenCV
frame = np.array(img)
# convert colors from BGR to RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# write the frame
out.write(frame)
# show the frame
# cv2.imshow("screenshot", frame)
# if the user clicks q, it exits
if cv2.waitKey(1) == ord("q"):
break
# make sure everything is closed when exited
cv2.destroyAllWindows()
out.release()
How I call it:
import tasks
p = tasks.VidRec()
p.screen()
I get an error even though I made default parameters in the class "def screen(self,fps=12.0,time=10):"
out = cv2.VideoWriter("output.avi", fourcc, self.fps, (SCREEN_SIZE))
AttributeError: 'VidRec' object has no attribute 'fps'

Related

Resizing video using opencv and saving it

I'm trying to re-size the video using opencv and then save it back to my system.The code works and does not give any error but output video file is corrupted. The fourcc I am using is mp4v works well with .mp4 but still the output video is corrupted. Need Help.
import numpy as np
import cv2
import sys
import re
vid=""
if len(sys.argv)==3:
vid=sys.argv[1]
compress=int(sys.argv[2])
else:
print("File not mentioned or compression not given")
exit()
if re.search('.mp4',vid):
print("Loading")
else:
exit()
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
def rescale_frame(frame, percent=75):
width = int(frame.shape[1] * percent/ 100)
height = int(frame.shape[0] * percent/ 100)
dim = (width, height)
return cv2.resize(frame, dim, interpolation =cv2.INTER_AREA)
FPS= 15.0
FrameSize=(frame.shape[1], frame.shape[0])
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('Video_output.mp4', fourcc, FPS, FrameSize, 0)
while(cap.isOpened()):
ret, frame = cap.read()
# check for successfulness of cap.read()
if not ret: break
rescaled_frame=rescale_frame(frame,percent=compress)
# Save the video
out.write(rescaled_frame)
cv2.imshow('frame',rescaled_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
The problem is the VideoWriter initialization.
You initialized:
out = cv2.VideoWriter('Video_output.mp4', fourcc, FPS, FrameSize, 0)
The last parameter 0 means, isColor = False. You are telling, you are going to convert frames to the grayscale and then saves. But there is no conversion in your code.
Also, you are resizing each frame in your code based on compress parameter.
If I use the default compress parameter:
cap = cv2.VideoCapture(0)
if cap.isOpened():
ret, frame = cap.read()
rescaled_frame = rescale_frame(frame)
(h, w) = rescaled_frame.shape[:2]
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter('Video_output.mp4',
fourcc, 15.0,
(w, h), True)
else:
print("Camera is not opened")
Now we have initialized the VideoWriter with the desired dimension.
Full Code:
import time
import cv2
def rescale_frame(frame_input, percent=75):
width = int(frame_input.shape[1] * percent / 100)
height = int(frame_input.shape[0] * percent / 100)
dim = (width, height)
return cv2.resize(frame_input, dim, interpolation=cv2.INTER_AREA)
cap = cv2.VideoCapture(0)
if cap.isOpened():
ret, frame = cap.read()
rescaled_frame = rescale_frame(frame)
(h, w) = rescaled_frame.shape[:2]
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter('Video_output.mp4',
fourcc, 15.0,
(w, h), True)
else:
print("Camera is not opened")
while cap.isOpened():
ret, frame = cap.read()
rescaled_frame = rescale_frame(frame)
# write the output frame to file
writer.write(rescaled_frame)
cv2.imshow("Output", rescaled_frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
cv2.destroyAllWindows()
cap.release()
writer.release()
Possible Question: I don't want to change my VideoWriter parameters, what should I do?
Answer: Then you need to change your frames, to the gray image:
while cap.isOpened():
# grab the frame from the video stream and resize it to have a
# maximum width of 300 pixels
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

How to increase the fps of screen recorder in cv2

I have written a code to record the screen recorder using python but when i see the output then i found that its fps is very low .Is there any better code than mine to increase the fps of the screen recorder.
If yes then please reply.
Here is mine code:-
import cv2
import numpy as np
import pyautogui
import datetime
# display screen resolution, get it from your OS settings
SCREEN_SIZE = (1366, 768)
# define the codec
fourcc = cv2.VideoWriter_fourcc(*"XVID")
# create the video write object
now = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
out = cv2.VideoWriter("screen recorder"+now+".avi", fourcc, 5.0, (SCREEN_SIZE))
while True:
img = pyautogui.screenshot()
frame = np.array(img)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
out.write(frame)
cv2.imshow("screenshot", frame)
# if the user clicks q, it exits
if cv2.waitKey(1) == ord("q"):
break
cv2.destroyAllWindows()
out.release()
img = pyautogui.screenshot(region=(0, 0, 300, 400))
The third parameter to the cv2.VideoWriter constructor is the frame rate (https://docs.opencv.org/3.4/dd/d9e/classcv_1_1VideoWriter.html#ac3478f6257454209fa99249cc03a5c59). Currently, you have it set to 5.0. For example, for 30 fps, instantiate the VideoWriter with:
out = cv2.VideoWriter("screen recorder"+now+".avi", fourcc, 30.0, (SCREEN_SIZE))
EDIT: In order to also read in images at the correct framerate, we can pause the while loop using the waitKey function. We can re-write the OP's code like so:
import cv2
import numpy as np
import pyautogui
import datetime
import time
# display screen resolution, get it from your OS settings
SCREEN_SIZE = (1366, 768)
FRAME_RATE = 30.0 # desired frame-rate
# define the codec
fourcc = cv2.VideoWriter_fourcc(*"XVID")
# create the video write object
now = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
out = cv2.VideoWriter("screen recorder"+now+".avi", fourcc, FRAME_RATE, (SCREEN_SIZE))
while True:
st = time.time() # collect start time
img = pyautogui.screenshot()
frame = np.array(img)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
out.write(frame)
cv2.imshow("screenshot", frame)
en = time.time() # collect end time
# calculate time to wait before next frame:
delay = max(0, (1 / FRAME_RATE - (en - st)) * 1000)
# if the user clicks q, it exits
if cv2.waitKey(delay) == ord("q"):
break
cv2.destroyAllWindows()
out.release()
img = pyautogui.screenshot(region=(0, 0, 300, 400))
Note: If collecting the frames is too slow (requires more than 1 / FRAMERATE seconds), then you may want to reduce the frame rate or the resolution.

pyautogui.screenshot region is not working

When I try to capture a video screenshot of my screen in a region suddenly the .avi output file becomes a 7kb.
The is no error, so I do not know how to fix this
The output video is fine before selecting the region.
how can i fix this problem?
import cv2
import numpy as np
import pyautogui
# display screen resolution, get it from your OS settings
import tkinter as tk
from PIL.Image import Image
root = tk.Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
SCREEN_SIZE = (screen_width, screen_height)
fourcc = cv2.VideoWriter_fourcc(*"XVID")
# create the video write object
out = cv2.VideoWriter("output.avi", fourcc, 20.0, (SCREEN_SIZE))
while True:
# make a screenshot
img = pyautogui.screenshot(region=(350, 800, 500, 150))
# convert these pixels to a proper numpy array to work with OpenCV
frame = np.array(img)
# convert colors from BGR to RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# write the frame
out.write(frame)
# show the frame
cv2.imshow("screenshot", frame)
# if the user clicks q, it exits
if cv2.waitKey(1) == ord("q"):
break
# make sure everything is closed when exited
cv2.destroyAllWindows()
out.release()

Opencv-python cannot write video file

I am trying to save a video file with opencv3 in python. The video that I want to save comes from another video file which I modify for tracking purposes. What I get is an empty .avi file, and I don't understand why.
If it helps, I'm on OSX.
Thanks for the help.
Here is the relevant part of the code:
import cv2
import numpy as np
cap = cv2.VideoCapture('Vid.avi')
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (width-110, heigh-210))
while (cap.isOpened()):
success, frame = cap.read()
if success:
hsv_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_frame,lower,upper) #lower and upper are defined in another part of the code
hsv_res = cv2.bitwise_and(hsv_frame,hsv_frame, mask= mask)
out.write(hsv_res)
cv2.imshow('Video', hsv_res)
if cv2.waitKey(50) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()

OpenCV2 / Python - How to ignore brightness with image matching function

My goal is to detect a movement on the camera.
The code below works, but sometimes when the brightness changes, It enables the capture as If a movement was detected.
from PIL import ImageGrab
import cv2
import time
import numpy
from os.path import expanduser
try:
import cPickle as pickle
except:
import pickle
def matchFrame(image1,image2):
origin = image1
origin=cv2.cvtColor(origin, cv2.COLOR_BGR2GRAY)
image = image2
result = cv2.matchTemplate(origin, image, cv2.TM_CCOEFF_NORMED)
minVal,maxVal,minLoc,maxLoc = cv2.minMaxLoc(result)
threshold = 0.90
loc = numpy.where( result >= threshold)
if loc[0].size==0 and loc[1].size==0:
return False
else:
return True
def run():
cap = cv2.VideoCapture(0)
ret, firstframe = cap.read()
inc=0
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if matchFrame(firstframe,gray):
pass
else:
cv2.imwrite("path%s"%inc);
inc=inc+1
cv2.waitKey(1)
if __name__ == "\__main\__"
run()
The method "matchFrame" use cv2.matchTemplate(origin, image, cv2.TM_CCOEFF_NORMED) to compare image. If they are similar, It returns False I already tried to change the threshold but It does not work.
The method "run" is for the video capture and call the method above to compare the first frame with the current frame.
I personnaly think that It's all about cv2.TM_CCOEFF_NORMED...
Do you have any suggestions?

Categories

Resources