Как я могу использовать экран в качестве видеовхода для Darkflow
Я тренировал darkflow на своем наборе данных и получаю хороший результат! Я могу накормить его заранее записанным изображением или видео, и оно нарисует ограничивающие рамки вокруг нужных вещей, выиграй!
Теперь я хотел бы запустить его вживую, как это было сделано с камерами, за исключением того, что я хотел бы, чтобы мой канал был с экрана, а не с камеры. У меня есть определенное окно, которое запускается из определенного процесса, или я могу просто взять часть экрана (из координат), либо подходит для моего приложения.
В настоящее время я использую захват изображений PIL, а затем передаю изображения в darkflow, но это выглядит довольно медленно (возможно, несколько кадров в секунду), совсем не то же самое, что 30 кадров в секунду, которые вы можете получить с видеофайлами!
1 ответ
Я получаю более 25 кадров в секунду с Python MSS на моем медленном ноутбуке под Ubuntu.
Вот пример:
from mss import mss
from PIL import Image
import time
def capture_screenshot():
with mss() as sct:
monitor = sct.monitors[1]
sct_img = sct.grab(monitor)
# Convert to PIL/Pillow Image
return Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')
N = 100
t = time.time()
for _ in range(N):
capture_screenshot()
print ("Frame rate = %.2f fps" % (N/(time.time()-t)))
Выход:
Frame rate = 27.55 fps
Я получил более 40 кадров в секунду с этим сценарием (на i5-7500 3,4 ГГц, GTX 1060, 48 ГБ ОЗУ). Для захвата экрана используется множество API. Среди них mss работает намного быстрее и не сложен в использовании. Вот реализация mss с darkflow ( YOLOv2), в которой 'mon' определяет область, к которой вы хотите применить прогноз на экране.
Параметры передаются в Darkflow, где указывается, какой конфигурационный файл и контрольную точку мы хотим использовать, порог обнаружения и насколько этот процесс занимает GPU. Перед запуском этого скрипта у нас должна быть хотя бы одна обученная модель (или контрольная точка Tensorflow). Здесь load - номер контрольной точки.
Если вы считаете, что сеть обнаруживает слишком много ограничивающих рамок, я рекомендую вам снизить порог.
import numpy as np
import cv2
import glob
from moviepy.editor import VideoFileClip
from mss import mss
from PIL import Image
from darkflow.net.build import TFNet
import time
options = {
'model' : 'cfg/tiny-yolo-voc-1c.cfg' ,
'load' : 5500,
'threshold' : 0.1,
'gpu' : 0.7 }
tfnet = TFNet( options )
color = (0, 255, 0) # bounding box color.
# This defines the area on the screen.
mon = {'top' : 10, 'left' : 10, 'width' : 1000, 'height' : 800}
sct = mss()
previous_time = 0
while True :
sct.get_pixels(mon)
frame = Image.frombytes( 'RGB', (sct.width, sct.height), sct.image )
frame = np.array(frame)
# image = image[ ::2, ::2, : ] # can be used to downgrade the input
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = tfnet.return_predict( frame )
for result in results :
tl = ( result['topleft']['x'], result['topleft']['y'] )
br = ( result['bottomright']['x'], result['bottomright']['y'] )
label = result['label']
confidence = result['confidence']
text = '{} : {:.0f}%'.format( label, confidence * 100 )
frame = cv2.rectangle( frame, tl, br, color, 5 )
frame = cv2.putText( frame, text, tl, cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 0), 2 )
cv2.imshow ( 'frame', frame )
if cv2.waitKey ( 1 ) & 0xff == ord( 'q' ) :
cv2.destroyAllWindows()
txt1 = 'fps: %.1f' % ( 1./( time.time() - previous_time ))
previous_time = time.time()
print txt1