Recientemente, al hacer predicciones de video en tiempo real de llamas, siempre encuentro problemas de demora, que van desde unos pocos segundos a diez segundos o decenas de segundos, lo cual es difícil de aceptar.
El siguiente esquema puede controlar la demora en 1 segundo.
La idea general: adoptar kafka
referencia de instalación de kafka Los
productores de
kafka de instalación para obtener secuencias de video obtienen cada cuadro, modelo de algoritmo de procesamiento de llamadas, el cuadro procesado en kafka, los consumidores se suscriben al video de noticias de kafka.
El código de productor es el siguientekafka_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)
El código de consumidor es el siguiente 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)
mayor optimización
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)
También puede optimizar, consulte el siguiente esquema para
leer la transmisión de video de múltiples cámaras web (Haikang \ Dahua) (usando opencv-python) para resolver el problema del retraso de lectura en tiempo real