I am trying to capture the screen and show the images continuously using opencv-python. But for some reason the images are not stacking on top of each others like normally. Please look at the source code and the screenshot below. I am on ubuntu 18.04. Thanks!!
import time
import cv2
import mss
import numpy as np
with mss.mss() as sct:
# Part of the screen to capture
monitor = {"top": 40, "left": 0, "width": 800, "height": 640}
while True:
last_time = time.time()
# Get raw pixels from the screen, save it to a Numpy array
img = np.array(sct.grab(monitor))
# Display the picture
cv2.imshow('frame', img)
print("fps: {}".format(1 / (time.time() - last_time)))
# Press "q" to quit
if cv2.waitKey(1) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
Related
I am trying to make a screen recorder using python opencv along with the mss library.
I can not get it to record a video. Whenever I stop the application - the file size becomes static such as sizes as for example 6kB - depending on the codec I used.
I have read that the capture must be the same size as the screen resolution which it is - but it still does not record.
I have also tried to use various codecs such as *'MP4V' but whatever I try - it does not save a proper recording.
I am using a MAC with a m1 processor if that matters.
import numpy as np
import cv2
import glob
from moviepy.editor import VideoFileClip
from mss import mss
from PIL import Image
import time
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('outpute.avi', fourcc, 60, (2560,1600))
with mss() as sct:
# Part of the screen to capture
monitor = {"top": 0, "left": 0, "width": 2560, "height": 1600}
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))
# Display the picture
cv2.imshow("OpenCV/Numpy normal", img)
# Write the image
out.write(img)
print("fps: {}".format(1 / (time.time() - last_time)))
# Press "q" to quit
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
this tutorial is working, good luck!
After debugging I noticed that monitor values has to be divided by 2 in order to work. No idea why this is the case - but I debugged it and saw that this was the case.
I also realized that I had to convert from BGR to RGB before I am writing it to a video file. Otherwise it won't work.
I also changed the format, but it was not part of the problem I do not believe.
Here is the working code
import numpy as np
import cv2
import glob
from moviepy.editor import VideoFileClip
from mss import mss
from PIL import Image
import time
import pyautogui
SCREEN_SIZE = tuple((2880,1800))
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mp4', fourcc, 60, (SCREEN_SIZE))
with mss() as sct:
# Part of the screen to capture
monitor = {"top": 0, "left": 0, "width": 1440, "height": 900}
while True:
last_time = time.time()
img = np.array(sct.grab(monitor))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
out.write(img)
print("fps: {}".format(1 / (time.time() - last_time)))
if cv2.waitKey(2) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
(Ignore the extra libraries I added)
I am trying to screenshot using mss library add display it using below code but getting same error every time.
Is there a fix for this error
TypeError: Expected Ptr<cv::UMat> for argument 'mat'
** I am using this in Macos not windows
import cv2 as cv
import numpy as np
import os
from time import time
from mss import mss
os.chdir(os.path.dirname(os.path.abspath(__file__)))
loop_time = time()
with mss() as sct:
while (True):
monitor_1 = sct.monitors[1] # Identify the display to capture
screenshot = sct.grab(monitor_1)
cv.imshow('result', screenshot)
print('FPS {}',format(1 / (time() - loop_time)))
loop_time = time()
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
break
print('done')
You have to convert "screenshot" to cv::UMat :
import time
import cv2
import mss
import numpy
with mss.mss() as sct:
# Part of the screen to capture
monitor = {"top": 40, "left": 0, "width": 800, "height": 640}
while "Screen capturing":
last_time = time.time()
# Get raw pixels from the screen, save it to a Numpy array
img = numpy.array(sct.grab(monitor))
# Display the picture
cv2.imshow("OpenCV/Numpy normal", img)
# Display the picture in grayscale
# cv2.imshow('OpenCV/Numpy grayscale',
# cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY))
print("fps: {}".format(1 / (time.time() - last_time)))
# Press "q" to quit
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
This is example from here
I am trying to grab screen using MSS and pass it to a Yolov3 model detection. The problem is that the Yolo expects data to be in 3 dimensions and MSS grab method returns data in 4-dimensions. How can we convert the image data into 3-dimensions?
import time
import cv2
import mss
import numpy as np
def main():
mon = {"top": 0, "left": 0, "width": 850, "height": 512}
fps = 0
sct = mss.mss()
last_time = time.time()
while True:
img = np.asarray(sct.grab(mon))
# here is something that I tried
img= img.reshape(-2,512,850,1)
#print(img.shape) #(512, 850, 4)
#print('The Loop Took {} seconds'.format(time.time()-last_time))
last_time = time.time()
cv2.imshow('CSGO', img)
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
return fps
I am following this project to make a AI that plays Google Chrome Dino game. I am stuck at a point while capturing screen feed to generate training data. I am new to CV
The project is supposed to supposed to break the video feed and save the CSV file in cv2.waitKey(25) & 0xFF == ord('q'): condition. Which I believe is when key "q" is pressed. But nothing happens when I press 'q'. The print statement in this if condition doesn't print when I press q.
Also although the console prints the print statement in 'up' ,'down' or 't' key pressed condition but the
cv2.imwrite('./images/frame_(0).jpg'.format(x), img)
Doesn't seem to be working as no images in the images folder are saved.
Here is the code
import cv2
from mss import mss
import numpy as np
import keyboard
#Captures dinasour run for given coordinates
def start():
"""
Capture video feed frame by frame, crops out coods and the dino then process
"""
sct = mss()
coordinates = {
'top': 168,
'left': 230,
'width': 624,
'height': 141
}
with open('actions.csv','w') as csv:
x = 0
while True:
img = np.array(sct.grab(coordinates))
#crop out the dino from the image array
img = img[::,75:624]
#edge detection to reduce ammount of image processing work
img = cv2.Canny(img, threshold1=100, threshold2=200)
if keyboard.is_pressed('up arrow'):
cv2.imwrite('./images/frame_(0).jpg'.format(x), img)
csv.write('1\n')
print('jump write')
x += 1
if keyboard.is_pressed('down arrow'):
cv2.imwrite('./images/frame_(0).jpg'.format(x), img)
csv.write('2\n')
print('duck')
x += 1
if keyboard.is_pressed('t'):
cv2.imwrite('./images/frame_(0).jpg'.format(x), img)
csv.write('0\n')
print('nothing')
x += 1
# break the video feed
if cv2.waitKey(25) & 0xFF == ord('q'):
csv.close()
cv2.destroyAllWindows()
print('Exited')
break
def play():
sct = mss()
coordinates = {
'top': 168,
'left': 230,
'width': 624,
'height': 141
}
img = np.array(sct.grab(coordinates))
# crop out the dinosaur from the image array
img = img[::,75:615]
# edge detection to reduce amount of image processing work
img = cv2.Canny(img, threshold1=100, threshold2=200)
cv2.waitKey() does only work if you press the key while an OpenCV window (e.g. created with cv2.imshow()) is focused. It seems for me as you don't use GUI features of OpenCV at all.
If you have a OpenCV GUI in your program, focus it and then press the key.
If not, and if you don't want to implement one, why not use keyboard.isPressed()?
How do I use python, mss, and opencv to capture my computer screen and save it as an array of images to form a movie? I am converting to gray-scale so it can be a 3 dimensional array. I would like to store each 2d screen shot in a 3d array for viewing and processing. I am having a hard time constructing an array that saves the sequence of screen shots as well as plays back the sequence of screen shots in cv2.
Thanks a lot
import time
import numpy as np
import cv2
import mss
from PIL import Image
with mss.mss() as sct:
fps_list=[]
matrix_list = []
monitor = {'top':40, 'left':0, 'width':800, 'height':640}
timer = 0
while timer <100:
last_time = time.time()
#get raw pizels from screen and save to numpy array
img = np.array(sct.grab(monitor))
img=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Save img data as matrix
matrix_list[timer,:,:] = img
#Display Image
cv2.imshow('Normal', img)
fps = 1/ (time.time()-last_time)
fps_list.append(fps)
#press q to quit
timer += 1
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
#calculate fps
fps_list = np.asarray(fps_list)
print(np.average(fps_list))
#playback image movie from screencapture
t=0
while t < 100:
cv.imshow('Playback',img_matrix[t])
t += 1
A clue perhaps, save screenshots into a list and replay them later (you will have to adapt the sleep time):
import time
import cv2
import mss
import numpy
with mss.mss() as sct:
monitor = {'top': 40, 'left': 0, 'width': 800, 'height': 640}
img_matrix = []
for _ in range(100):
# Get raw pizels from screen and save to numpy array
img = numpy.array(sct.grab(monitor))
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Save img data as matrix
img_matrix.append(img)
# Display Image
cv2.imshow('Normal', img)
# Press q to quit
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
# Playback image movie from screencapture
for img in img_matrix:
cv2.imshow('Playback', img)
# Press q to quit
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
use collections.OrderedDict() to saves the sequence
import collections
....
fps_list= collections.OrderedDict()
...
fps_list[timer] = fps