|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- 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()
-
-
-
-
-
-
|