tuoheng_algN/test/demo/demo1.py

222 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import copy
import json
import os
import time
from concurrent.futures import ThreadPoolExecutor
from multiprocessing import Queue, Process
from loguru import logger
import subprocess as sp
import cv2
import numpy as np
from aip import AipImageClassify
from enums.BaiduSdkEnum import BAIDUERRORDATA, VehicleEnumVALUE
from enums.ExceptionEnum import ExceptionType
from enums.ModelTypeEnum import ModelType
from exception.CustomerException import ServiceException
def get_recording_video_info(url):
try:
video_info = 'ffprobe -show_format -show_streams -of json %s' % url
p = sp.Popen(video_info, stdout=sp.PIPE, stderr=sp.PIPE, shell=True)
out, err = p.communicate(timeout=17)
if p.returncode != 0:
raise Exception("未获取视频信息!!!!!")
probe = json.loads(out.decode('utf-8'))
if probe is None or probe.get("streams") is None:
raise Exception("未获取视频信息!!!!!:")
video_stream = next((stream for stream in probe['streams'] if stream.get('codec_type') == 'video'), None)
if video_stream is None:
raise Exception("未获取视频信息!!!!!")
width = video_stream.get('width')
height = video_stream.get('height')
nb_frames = video_stream.get('nb_frames')
fps = video_stream.get('r_frame_rate')
up, down = str(fps).split('/')
fps = int(eval(up) / eval(down))
return (width, height, nb_frames, fps)
except Exception as e:
raise e
client = AipImageClassify(str(31096670), 'Dam3O4tgPRN3qh4OYE82dbg7', '1PGZ9LAXRR5zcT5MN9rHcW8kLBIS5DAa')
def vehicleDetect(client, iamge, options={}):
reply_num = 0
reply_value = None
while True:
try:
options["show"] = "true"
res_image = client.vehicleDetect(iamge,options)
error_code = res_image.get("error_code")
if error_code:
enum = BAIDUERRORDATA.get(error_code)
# 如果异常编码未知, 返回空值
if enum is None:
logger.error("百度云车辆检测异常error_code:{}", error_code)
return None
# 重试指定次数后,还是异常,输出统一内部异常
if enum.value[3] == 0:
if reply_value is None:
reply_value = 10
logger.error("百度云车辆检测异常error_code:{}, error_msg:{}, reply_num:{}", enum.value[0], enum.value[2], reply_num)
raise Exception()
# 重试指定次数后,还是异常,输出对应的异常
if enum.value[3] == 1:
if reply_value is None:
reply_value = 10
raise ServiceException(str(enum.value[0]), enum.value[2])
# 重试指定次数后,还是异常,输出空
if enum.value[3] == 2:
if reply_value is None:
reply_value = 10
if reply_num >= reply_value:
return None
return res_image
except ServiceException as s:
time.sleep(0.2)
reply_num += 1
if reply_num > reply_value:
logger.exception("车辆检测识别失败: {}", s.msg)
raise ServiceException(e.code, e.msg)
except Exception as e:
logger.exception("车辆检测失败: {}, 当前重试次数:{}", e, reply_num)
time.sleep(0.2)
reply_num += 1
if reply_num > reply_value:
logger.exception("车辆检测识别失败: {}", e)
raise ServiceException(ExceptionType.SERVICE_INNER_EXCEPTION.value[0],
ExceptionType.SERVICE_INNER_EXCEPTION.value[1])
def mark(content, info, img, color):
score = info.get("probability")
if score is None:
score = info.get("location").get("score")
text = "%s: %.2f]" % (content, score)
text_xy = (info.get("location").get("left"), info.get("location").get("top") - 25)
img_lu = (info.get("location").get("left"), info.get("location").get("top"))
img_rd = (info.get("location").get("left") + info.get("location").get("width"),
info.get("location").get("top") + info.get("location").get("height"))
cv2.putText(img, text, text_xy, cv2.FONT_HERSHEY_SIMPLEX, 1.0, color, 2, cv2.LINE_AA)
count = 1
if img.shape[1] > 1600:
count = 2
cv2.rectangle(img, img_lu, img_rd, color, count)
return img
def pull_stream(url, queue, nb_frames):
command = ['ffmpeg -re -y -i ' + url +' -f rawvideo -pix_fmt bgr24 -an -']
pull_p = sp.Popen(command, stdout=sp.PIPE, shell=True)
aa = 0
try:
while True:
if queue.qsize() == 200:
time.sleep(1)
continue
in_bytes = pull_p.stdout.read(width*height*3)
if in_bytes is not None and len(in_bytes) > 0:
img = np.frombuffer(in_bytes, np.uint8).reshape([height, width, 3])
queue.put({"status": "1", "img": img})
aa+=1
else:
if aa -10 > nb_frames:
queue.put({"status": "2"})
pull_p.terminate()
pull_p.wait()
break;
except Exception as e:
logger.exception("拉流异常: {}", e)
finally:
pull_p.terminate()
pull_p.wait()
def getQueue(queue):
eBody = None
try:
eBody = queue.get(block=False)
return eBody
except Exception as e:
pass
return eBody
def buildFrame(queue, senlin_mod, client, width, height, nb_frames, fps):
frames = []
status = None
for i in range(queue.qsize()):
frame_result = getQueue(queue)
if frame_result is None:
time.sleep(0.01)
continue
if frame_result.get("status") == '1':
frames.append((frame_result.get("img"), senlin_mod, client, width, height, nb_frames, fps))
else:
status = frame_result.get("status")
return frames, status
def process(frame):
try:
p_result, timeOut = frame[1].process(copy.deepcopy(frame[0]), frame[3])
or_result, or_image = cv2.imencode(".jpg", frame[0])
result = vehicleDetect(frame[2], or_image)
if result is not None:
vehicleInfo = result.get("vehicle_info")
if vehicleInfo is not None and len(vehicleInfo) > 0:
for i, info in enumerate(vehicleInfo):
value = VehicleEnumVALUE.get(info.get("type"))
if value is None:
logger.error("车辆识别出现未支持的目标类型type:{}", info.get("type"))
raise ServiceException(ExceptionType.SERVICE_INNER_EXCEPTION.value[0],
ExceptionType.SERVICE_INNER_EXCEPTION.value[1])
p_result[1] = mark(value.value[1], info, p_result[1], (255, 0, 255))
frame_merge = np.hstack((frame[0], p_result[1]))
return frame_merge
except Exception as e:
logger.exception("模型分析异常: {}", e)
return None
queue = Queue(200)
url ='/home/th/tuo_heng/dev/11.mp4'
width, height, nb_frames, fps = get_recording_video_info(url)
my_process = Process(target = pull_stream, args=(url, queue, nb_frames))
#启动子进程
my_process.start()
current_path = os.path.abspath(os.path.dirname(__file__))
import GPUtil
senlin_mod = Model(str(GPUtil.getAvailable()[0]), [2,3,4], logger, "11111", ModelType.FOREST_FARM_MODEL)
or_video_file = cv2.VideoWriter("aaa.mp4", cv2.VideoWriter_fourcc(*'mp4v'), fps,
(int(width) * 2, int(height)))
with ThreadPoolExecutor(max_workers=3) as t:
task_frame = None
while True:
frames = []
status = None
if task_frame is not None:
frames, status = task_frame.result()
task_frame = t.submit(buildFrame, queue, senlin_mod, client, width, height, nb_frames, fps)
if len(frames) == 0 and status is None:
time.sleep(0.02)
continue
if frames is not None and len(frames) > 0:
for result in t.map(process, frames):
if result is not None:
or_video_file.write(result)
if status is None:
continue
if status.get("status") == "2":
t.shutdown(wait=False)
or_video_file.release()
t.shutdown(wait=False)
or_video_file.release()