最近、炎のリアルタイムビデオ予測を行うと、数秒から10秒、または数十秒の範囲の遅延の問題が常に発生しますが、これは受け入れがたいものです。
次のスキームでは、1秒以内に遅延を制御できます。
全体的なアイデア:kafkaを採用する
kafkaインストールリファレンスインストールkafka
プロデューサーはビデオストリームを取得し、各フレームを取得し、処理アルゴリズムモデルを呼び出し、処理されたフレームをkafkaに取り込み、
コンシューマーはkafkaニュースビデオをサブスクライブします。
プロデューサーコードは次のとおりですkafka_producer.py
# -*- coding: utf-8 -*-
from kafka import KafkaProducer
from imutils.video import VideoStream
import requests
import imutils
import numpy as np
import time
import cv2
from PIL import Image
from io import BytesIO
import base64
import json
def publish_video(server, topic, rtsp, api_url):
producer = KafkaProducer(bootstrap_servers=server)
vs = VideoStream(src=rtsp).start()
time.sleep(2.0)
print("publishing video...")
while True:
frame = vs.read()
frame = process(frame, api_url)
frame = imutils.resize(frame, width=400)
# send to kafka topic
producer.send(topic, frame.tobytes())
vs.stop()
def process(frame, api_url):
img = Image.fromarray(frame)
output_buffer = BytesIO() # 创建一个BytesIO
img.save(output_buffer, format='JPEG') # 写入output_buffer
byte_data = output_buffer.getvalue() # 在内存中读取
image_base64 = base64.b64encode(byte_data).decode() # 转为BASE64
data = json.dumps(
{"image": image_base64, "visual_result": "True", "username": "xsrt", "password": "dGVzdC1wd2QxMjM="})
headers = {"Content-Type": "application/json"}
response = requests.post(api_url, data=data, headers=headers)
result = response.text
result = json.loads(result)
try:
base64_img = result["base64"]
process_img = base64.b64decode(base64_img)
img = cv2.imdecode(np.frombuffer(process_img, np.uint8), cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
except:
img = frame
return img
def process_list(result):
for i in result:
result_i = i
result_i_bbox = result_i["bbox"]
for i in range(len(result_i_bbox)):
result_i_bbox[i] = result_i_bbox[i] * 2
return result
if __name__ == '__main__':
server = '192.168.20.99:9092'
topic = 'run'
# rtsp = 'rtsp://admin:[email protected]:554/h264/ch1/main/av_stream'
rtsp = 0
api_url = 'http://192.168.20.99:8191/fire/json'
publish_video(server, topic, rtsp, api_url)
コンシューマーコードは次のとおりです kafka_consumer.py
from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import time
import cv2
from kafka import KafkaConsumer
import sys
def showCam(server, topic, window_name):
consumer = KafkaConsumer(
topic,
bootstrap_servers=[server])
fps = FPS().start()
for msg in consumer:
# print(msg)
decoded = np.frombuffer(msg.value, np.uint8)
# print(decoded.size)
# decoded = decoded.reshape(225, 400, 3)
decoded = decoded.reshape((int)(decoded.size / (400 * 3)), 400, 3)
cv2.namedWindow(window_name, flags=cv2.WINDOW_FREERATIO)
cv2.imshow(window_name, decoded)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
fps.update()
fps.stop()
cv2.destroyAllWindows()
if __name__ == '__main__':
server = '192.168.20.99:9092'
topic = 'run'
window_name = 'fire'
showCam(server, topic, window_name)
さらなる最適化
kafka_producer.py
# -*- coding: utf-8 -*-
from kafka import KafkaProducer
from imutils.video import VideoStream
import requests
import imutils
import numpy as np
import time
import cv2
from PIL import Image
from io import BytesIO
import base64
import json
def publish_video(server, topic, rtsp, api_url):
producer = KafkaProducer(bootstrap_servers=server)
vs = VideoStream(src=rtsp).start()
time.sleep(2.0)
print("publishing video...")
i = 0
a = 5
while True:
i = i +1
if i % a == 0:
frame = vs.read()
if q.qsize() > 1:
q.get()
else:
q.put(frame)
# frame = process(frame)
# frame = imutils.resize(frame, width=400)
frame = q.get()
if frame is not None:
frame = imutils.resize(frame, width=400)
# frame = detection(frame, 'pretrained.prototxt.txt', 'pretrained.caffemodel')
frame = process(frame)
# send to kafka topic
producer.send(topic, frame.tobytes())
vs.stop()
def process(frame, api_url):
img = Image.fromarray(frame)
output_buffer = BytesIO() # 创建一个BytesIO
img.save(output_buffer, format='JPEG') # 写入output_buffer
byte_data = output_buffer.getvalue() # 在内存中读取
image_base64 = base64.b64encode(byte_data).decode() # 转为BASE64
data = json.dumps(
{"image": image_base64, "visual_result": "True", "username": "xsrt", "password": "dGVzdC1wd2QxMjM="})
headers = {"Content-Type": "application/json"}
response = requests.post(api_url, data=data, headers=headers)
result = response.text
result = json.loads(result)
try:
base64_img = result["base64"]
process_img = base64.b64decode(base64_img)
img = cv2.imdecode(np.frombuffer(process_img, np.uint8), cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
except:
img = frame
return img
def process_list(result):
for i in result:
result_i = i
result_i_bbox = result_i["bbox"]
for i in range(len(result_i_bbox)):
result_i_bbox[i] = result_i_bbox[i] * 2
return result
if __name__ == '__main__':
server = '192.168.20.99:9092'
topic = 'run'
# rtsp = 'rtsp://admin:[email protected]:554/h264/ch1/main/av_stream'
rtsp = 0
api_url = 'http://192.168.20.99:8191/fire/json'
publish_video(server, topic, rtsp, api_url)
最適化することもできます。次のスキームを参照して、複数の(Haikang \ Dahua)Webカメラのビデオストリームを
読み取り(opencv-pythonを使用)、リアルタイムの読み取り遅延の問題を解決します。