如何将屏幕用作 darkflow 的视频输入

How can I use the screen as a video input to darkflow

我已经在我的数据集上训练了 darkflow 并取得了不错的效果!我可以为它提供预先录制的图像或视频,它会在正确的事物周围绘制边界框,赢了!

现在我想 运行 像使用摄像头供稿一样直播它,只是我希望我的供稿来自屏幕,而不是摄像头。我有一个特定的 window,它是从特定进程启动的,或者我可以只截取屏幕的一部分(来自坐标),这对我的应用程序来说都很好。

目前我使用 PILs 图像抓取,然后将图像送入 darkflow,但这感觉很慢(可能每秒几帧),与视频文件所能达到的 30 左右 fps 完全不同!

我在 Ubuntu 下的慢速笔记本电脑上使用 Python MSS 获得超过 25 fps。

这是一个例子:

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 fps(在 i5-7500 3.4GHz、GTX 1060、48GB RAM 上)。 有很多用于捕获屏幕的 API。其中,mss 运行s 速度要快很多,也不难用。这是一个带有 darkflow(YOLOv2) 的 mss 实现,其中 'mon' 定义了您要在屏幕上应用预测的区域。

options 传递给 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