我想用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
这样,您要丢弃的帧确实会丢失,并且不会出现延迟。
答案 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)