import os,cv2,time
import numpy as np
import argparse
from deploy.python.infer import Detector
from deploy.pipeline.ppvehicle.vehicle_plate import PlateRecognizer
from deploy.python.visualize import visualize_box_mask,visualize_attr,visualize_vehicleplate
from deploy.pipeline.pipe_utils import crop_image_with_det
from deploy.pipeline.datacollector import Result
from deploy.python.preprocess import decode_image
class chepai_Detector():
def __init__(self,args,cfg) -> None:
self.det_predictor = Detector(cfg['obj_det_model_dir'], args.device)
self.vehicleplate_detector = PlateRecognizer(args,cfg)
def visualize_image(self,im_files, images, result,output_dir, thresh):
start_idx, boxes_num_i = 0, 0
det_res = result.get('det')
human_attr_res = result.get('attr')
vehicle_attr_res = result.get('vehicle_attr')
vehicleplate_res = result.get('vehicleplate')
for i, (im_file, im) in enumerate(zip(im_files, images)):
if det_res is not None:
det_res_i = {}
boxes_num_i = det_res['boxes_num'][i]
det_res_i['boxes'] = det_res['boxes'][start_idx:start_idx +
boxes_num_i, :]
im = visualize_box_mask(
im,
det_res_i,
labels=['target'],
threshold=thresh)
im = np.ascontiguousarray(np.copy(im))
im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
if human_attr_res is not None:
human_attr_res_i = human_attr_res['output'][start_idx:start_idx
+ boxes_num_i]
im = visualize_attr(im, human_attr_res_i, det_res_i['boxes'])
if vehicle_attr_res is not None:
vehicle_attr_res_i = vehicle_attr_res['output'][
start_idx:start_idx + boxes_num_i]
im = visualize_attr(im, vehicle_attr_res_i, det_res_i['boxes'])
if vehicleplate_res is not None:
plates = vehicleplate_res['vehicleplate']
det_res_i['boxes'][:, 4:6] = det_res_i[
'boxes'][:, 4:6] - det_res_i['boxes'][:, 2:4]
im = visualize_vehicleplate(im, plates, det_res_i['boxes'])
img_name = os.path.split(im_file)[-1]
if not os.path.exists(output_dir):
os.makedirs(output_dir)
out_path = os.path.join(output_dir, img_name)
cv2.imwrite(out_path, im)
print("save result to: " + out_path)
start_idx += boxes_num_i
def detect(self,img_path,thresh,visual,output_dir):
pipeline_res = Result()
img = [decode_image(f, {})[0] for f in img_path]
det_res = self.det_predictor.predict_image(img_path, visual=False)
det_res = self.det_predictor.filter_box(det_res,thresh)
pipeline_res.update(det_res, 'det')
crop_inputs = crop_image_with_det(img, det_res)
platelicenses = []
for crop_input in crop_inputs:
platelicense = self.vehicleplate_detector.get_platelicense(crop_input)
platelicenses.extend(platelicense['plate'])
vehicleplate_res = {'vehicleplate': platelicenses}
pipeline_res.update(vehicleplate_res, 'vehicleplate')
if visual:
self.visualize_image(img_path, img, pipeline_res, thresh=thresh,output_dir=output_dir)
if __name__ == '__main__':
# 创建解析器
parser = argparse.ArgumentParser(description='jiexicanshu')
parser.add_argument('--device', type=str, default='gpu', help='选择使用GPU还是CPU')
parser.add_argument('--enable_mkldnn', type=bool, default=False, help='')
args = parser.parse_args()
cfg = { 'det_model_dir': r'./output_inference/ch_PP-OCRv3_det_infer',
'det_limit_side_len': 736,
'det_limit_type': 'min',
'rec_model_dir': r'./output_inference/ch_PP-OCRv3_rec_infer',
'rec_image_shape': [3, 48, 320],
'rec_batch_num': 6,
'word_dict_path': 'deploy/pipeline/ppvehicle/rec_word_dict.txt',
'enable': True,
'obj_det_model_dir': r'./output_inference/mot_ppyoloe_l_36e_ppvehicle'}
img_path = [r"./test.jpg"] #待识别图片
thresh = 0.5 #过滤阈值
visual = True #是否可视化
output_dir = r'./test_detection' #图片可视化后存放路径
Detector_chepai = chepai_Detector(args=args,cfg=cfg)
for i in range(100):
a = time.time()
Detector_chepai.detect(img_path,thresh,visual,output_dir)
b = time.time()
print(b-a)
需要注意的地方:
1.如果使用CPU推理,则将parser.add_argument(‘–device’, type=str, default=‘gpu’, help=‘选择使用GPU还是CPU’)中的default='gpu’改为default='cpu’即可.
2.下载目标检测模型(地址:https://bj.bcebos.com/v1/paddledet/models/pipeline/mot_ppyoloe_l_36e_ppvehicle.zip)以及OCR模型(OCR模型细分为检测模型(地址:https://bj.bcebos.com/v1/paddledet/models/pipeline/ch_PP-OCRv3_det_infer.tar.gz)和识别模型(地址:https://bj.bcebos.com/v1/paddledet/models/pipeline/ch_PP-OCRv3_rec_infer.tar.gz)),将以上压缩包下载到"自己的路径\PaddleDetection-release-2.4\output_inference"下并解压.
3.将img_path以及out_put_dir更改为自己待检测图片以及检测完后存储的路径即可.
4.改代码中默认将图片推理100次,若有需要,请自行更改
import os,cv2,time
import numpy as np
import argparse
from deploy.python.infer import Detector
from deploy.pipeline.ppvehicle.vehicle_plate import PlateRecognizer
from deploy.python.visualize import visualize_box_mask,visualize_attr,visualize_vehicleplate
from deploy.pipeline.pipe_utils import crop_image_with_det
from deploy.pipeline.datacollector import Result
from deploy.python.preprocess import decode_image
class chepai_Detector():
def __init__(self,args,cfg) -> None:
self.det_predictor = Detector(cfg['obj_det_model_dir'], args.device)
self.vehicleplate_detector = PlateRecognizer(args,cfg)
def visualize_image(self,im_files, images, result,output_dir, thresh):
start_idx, boxes_num_i = 0, 0
det_res = result.get('det')
human_attr_res = result.get('attr')
vehicle_attr_res = result.get('vehicle_attr')
vehicleplate_res = result.get('vehicleplate')
for i, (im_file, im) in enumerate(zip(im_files, images)):
if det_res is not None:
det_res_i = {}
boxes_num_i = det_res['boxes_num'][i]
det_res_i['boxes'] = det_res['boxes'][start_idx:start_idx +
boxes_num_i, :]
im = visualize_box_mask(
im,
det_res_i,
labels=['target'],
threshold=thresh)
im = np.ascontiguousarray(np.copy(im))
im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
if human_attr_res is not None:
human_attr_res_i = human_attr_res['output'][start_idx:start_idx
+ boxes_num_i]
im = visualize_attr(im, human_attr_res_i, det_res_i['boxes'])
if vehicle_attr_res is not None:
vehicle_attr_res_i = vehicle_attr_res['output'][
start_idx:start_idx + boxes_num_i]
im = visualize_attr(im, vehicle_attr_res_i, det_res_i['boxes'])
if vehicleplate_res is not None:
plates = vehicleplate_res['vehicleplate']
det_res_i['boxes'][:, 4:6] = det_res_i[
'boxes'][:, 4:6] - det_res_i['boxes'][:, 2:4]
im = visualize_vehicleplate(im, plates, det_res_i['boxes'])
img_name = os.path.split(im_file)[-1]
if not os.path.exists(output_dir):
os.makedirs(output_dir)
out_path = os.path.join(output_dir, img_name)
cv2.imwrite(out_path, im)
print("save result to: " + out_path)
start_idx += boxes_num_i
def detect(self,img_path,thresh,visual,output_dir):
pipeline_res = Result()
img = [decode_image(f, {})[0] for f in img_path]
det_res = self.det_predictor.predict_image(img_path, visual=False)
det_res = self.det_predictor.filter_box(det_res,thresh)
pipeline_res.update(det_res, 'det')
crop_inputs = crop_image_with_det(img, det_res)
platelicenses = []
for crop_input in crop_inputs:
platelicense = self.vehicleplate_detector.get_platelicense(crop_input)
platelicenses.extend(platelicense['plate'])
vehicleplate_res = {'vehicleplate': platelicenses}
pipeline_res.update(vehicleplate_res, 'vehicleplate')
if visual:
self.visualize_image(img_path, img, pipeline_res, thresh=thresh,output_dir=output_dir)
if __name__ == '__main__':
# 创建解析器
parser = argparse.ArgumentParser(description='jiexicanshu')
parser.add_argument('--device', type=str, default='gpu', help='选择使用GPU还是CPU')
parser.add_argument('--enable_mkldnn', type=bool, default=False, help='')
args = parser.parse_args()
cfg = { 'det_model_dir': './output_inference/ch_PP-OCRv3_det_infer',
'det_limit_side_len': 736,
'det_limit_type': 'min',
'rec_model_dir': './output_inference/ch_PP-OCRv3_rec_infer',
'rec_image_shape': [3, 48, 320],
'rec_batch_num': 6,
'word_dict_path': 'deploy/pipeline/ppvehicle/rec_word_dict.txt',
'enable': True,
'obj_det_model_dir': r'./output_inference/mot_ppyoloe_l_36e_ppvehicle'}
img_path = [r"./test.jpg"]
thresh = 0.5
visual = True
output_dir = r'./test_detection'
Detector_chepai = chepai_Detector(args=args,cfg=cfg)
for i in range(100):
a = time.time()
Detector_chepai.detect(img_path,thresh,visual,output_dir)
b = time.time()
print(b-a)
5.1首先将视频抽帧(即将视频变为多张图片)
def chouzhen(self,video_path,output_dir):
cap = cv2.VideoCapture(video_path) # 获取视频对象
isOpened = cap.isOpened # 判断是否打开
# 视频信息获取
fps = cap.get(cv2.CAP_PROP_FPS)
imageNum = 0
sum=0
timef=1 #隔1帧保存一张图片
while (isOpened):
sum+=1
(frameState, frame) = cap.read() # 记录每帧及获取状态
if frameState == True and (sum % timef==0):
# 格式转变,BGRtoRGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 转变成Image
frame = Image.fromarray(np.uint8(frame))
frame = np.array(frame)
# RGBtoBGR满足opencv显示格式
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
imageNum = imageNum + 1
fileName = os.path.join(output_dir,str(imageNum) + '.jpg' ) # 存储路径
cv2.imwrite(fileName, frame, [cv2.IMWRITE_JPEG_QUALITY, 100])
print(fileName + " successfully write in") # 输出存储状态
elif frameState == False:
break
print('finish!')
cap.release()
参数介绍:
video_path:待检测的视频地址
output_dir:将视频转换为多张图片后的存储路径
5.2将检测完的众多图片再合成视频
def hebing(self,path, size):
filelist = os.listdir(path) # 获取该目录下的所有文件名
filelist.sort(key=lambda x: int(x[:-4])) ##文件名按数字排序
'''
fps:
帧率:1秒钟有n张图片写进去[控制一张图片停留5秒钟,那就是帧率为1,重复播放这张图片5次]
如果文件夹下有50张 534*300的图片,这里设置1秒钟播放5张,那么这个视频的时长就是10秒
'''
fps = 16
file_path =os.path.join(path , "test_video_1.mp4") # 导出路径
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 不同视频编码对应不同视频格式(例:'I','4','2','0' 对应avi格式)
video = cv2.VideoWriter(file_path, fourcc, fps, size)
for item in filelist:
print(item)
if item.endswith('.jpg'): # 判断图片后缀是否是.jpg
item = path + '/' + item
img = cv2.imread(item) # 使用opencv读取图像,直接返回numpy.ndarray 对象,通道顺序为BGR ,注意是BGR,通道值默认范围0-255。
video.write(img) # 把图片写进视频
video.release() # 释放
参数介绍:
path:检测完后的图片存储路径
size:检测完后图片的宽度和高度(tuple类型,example:(1920,1440))
5.3大致流程
Detector_chepai = chepai_Detector(args,cfg)
thresh = 0.5
visual = True
video_path = r'' #待检测视频的路径
output_dir = r'' #将待检测视频抽帧之后图片的存储路径
output_dir_detect = r'' #图片检测完后的存储路径
size = (480,270) #合并图片的宽度和高度
Detector_chepai.chouzhen(video_path,output_dir)
img_list = os.listdir(output_dir)
for i in img_list:
Detector_chepai.detect([os.path.join(output_dir,i)],thresh,visual,output_dir_detect)
Detector_chepai.hebing(output_dir_detect,size)
实例化检测类,给定各种参数,先将视频进行抽帧,将图片保存至output_dir路径下;之后用os.listdir(output_dir)遍历图片,使用detect()进行推理,推理完的图片将保存至output_dir_detect;最后使用hebiong()函数将output_dir_detect路径下的所有图片进行合并,并将合并后的视频输出到output_dir_detect文件夹下.