场景:公司有个 ip 摄像头在海港那边。然后这边想访问一个 url,然后就返回摄像头那时候的一帧的截图(其实是返回图像识别过的 json )。
但是每次都去连接那个 ip 摄像头太慢了,于是便想将该 Video 连接持续化,将其放入一个 dict 里存起来,而不是每次连接完之后都 release,这样不用每次访问都去连接一次。大概像下面这样:
pool = {}
def create(camId):
cap = cv2.VideoCapture(baseUrl+camId)
if camId in pool:
return True
if cap.isOpened():
print("连接摄像头成功")
capDict = {}
capDict['time'] = int(time.time() * 1000)
capDict['camera'] = cap
pool[camId] = capDict
然后我用 flask 搭建的后台,每次访问 url,便调用下面的 detectBoat()函数,从 dict 中取出对应 id 的 Video 摄像头连接。这样只要最开始创建一次,就可以不用每次访问 url 都连接一次了。
def detectBoat(camId):
cap = pool[camId]['camera']
retryLimit = 3
if cap.isOpened():
results = ""
while True:
success, frame = cap.read()
try:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
except cv2.error:
print('reading frame failed, retry after 1s...')
time.sleep(1)
continue
img_name = f'{int(time.time() * 1000)}.jpg'
cv2.imwrite(f"{image_folder}/{img_name}", frame)
print(f'截取了图片: {img_name}')
resp = urlopen(myurl) #让别的分析后台来分析,再返回 json
results = json.loads(resp.read())
print(f"船舶识别: {results}")
break
del success, frame
return results
else:
return '请先连接摄像头'
然后问题来了,我发现我每次调用那个可持续化的摄像头连接 cap 的时候,他返回给我的永远是这一帧后的下一帧图。就是比如说,我 4 点 1 分调用这个函数,返回给我 4 点 1 分 0 秒的图,然后我 5 点再调用,还是返回给我 4 点 1 分 0 秒的图的下一帧的图给我,我再调用,就返回给我再下一帧图,我怀疑他是不是将每帧图都缓存起来了?我怎样才能让他返回给我当前时间的图呢。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.