Python视频流跳过帧

时间:2019-03-18 18:04:56

标签: python http opencv image-processing e

我想用opencv和python实时搜索我的android手机的屏幕。 我的手机通过http流式传输其屏幕,而我正在使用以下代码读取流式传输:

host = "192.168.178.168:8080"
hoststr = 'http://' + host +  '/stream.mjpeg'
print 'Streaming ' + hoststr
stream=urllib2.urlopen(hoststr)
bytes=''
drop_count = 0
while True:
    bytes+=stream.read(1024)
    a = bytes.find('\xff\xd8')
    b = bytes.find('\xff\xd9')
    if a!=-1 and b!=-1:
        drop_count+=1
        if drop_count > 120:
            drop_count = 0
            jpg = bytes[a:b+2]
            bytes= bytes[b+2:]
            i=cv2.imdecode(np.fromstring(jpg,dtype=np.uint8),cv2.IMREAD_COLOR)
            cv2.imshow(hoststr,i)
            process_img(i)#my image processing
            if cv2.waitKey(1) ==27:
                exit(0)

问题是,我的屏幕搜索时间过长,并且延迟很大。由于我的手机发送的fps很大,因此我只想每秒或每两秒钟处理一张图像。我怎样才能做到这一点?我无法更改手机上的fps。 我可以在发送之前将手机上的屏幕图像调整为50%,但是如果将其调整为50%以上,我将无法再使用opencv查找即时消息。但是即使调整大小为50%,也延迟太多。 如果我做一个简单的计数器,仅处理每张2/10/30张图像无济于事。

编辑:我添加了我的简单计数器实现来丢帧,这无济于事。如果我不处理图像,无论是否有丢帧,我都会得到恒定的小延迟。

EDIT²:终于解决了它,可惜我不记得在哪里阅读了,但是使用openCV VideoCapture非常简单:

screen_capture = cv2.VideoCapture(stream_url) #init videocapture
drop_count = 0 #init drop counter
while True:
    drop_count+=1
    ret = screen_capture.grab() #grab frame but dont process it
    if drop_count % 5 == 0: #check if not dropping frame
        ret, img = self.screen_capture.retrieve() #process frame

这样,您要丢弃的帧确实会丢失,并且不会出现延迟。

1 个答案:

答案 0 :(得分:0)

我猜测延迟会很长,因为您只显示已处理的帧。实际上,每120帧中仅显示1个。并为接下来的120帧和处理时间显示该帧。那确实会使它显得迟钝。
您应该正常显示所有帧,并且每第120帧仅调用process_img()函数。
尝试是否可以改善问题:

if a!=-1 and b!=-1:
    drop_count+=1
    jpg = bytes[a:b+2]
    bytes= bytes[b+2:]
    i=cv2.imdecode(np.fromstring(jpg,dtype=np.uint8),cv2.IMREAD_COLOR)
    cv2.imshow(hoststr,i)
    if drop_count > 120: # only process every 120th frame
        drop_count = 0
        process_img(i)#my image processing
    if cv2.waitKey(1) ==27:
        exit(0)