其他
系列 | OpenVINO使用之行人属性识别
点击上方↑↑↑“OpenCV学堂”关注我
关注我们,技术干货第一时间送达!
OpenVINO不仅通过其IE组件实现加速推理,其提供的预训练库还支持各种常见的图像检测、分割、对象识别等的计算机视觉任务。前面小编写过一系列的文章详细介绍过OpenVINO的各种应用,可以看这里回顾一下:
这里分享一下如何通过OpenVINO提供的行人检测与行人属性识别模型实现一个实时的视频行人检测与属性识别的演示程序。先看一下效果:
模型
模型来自OpenVINO官方提供的预训练模型库
行人检测模型:
模型名称:
pedestrian-detection-adas-0002
输入格式:NCHW= [1x3x384x672]
输出格式:DetectionOut 类型 [1, 1, N, 7]
基于Caffe SSD MobileNet V1版本训练生成
行人属性识别模型:
模型名称:
person-attributes-recognition-crossroad-0230
输入格式:NCHW= [1x3x160x80]
输出格式:
输出层有三个,其中输出层名称为435的输出格式为
[ ] 是八个属性
另外两个输出层456,459表示两个颜色位置
基于pytorch训练生成的分类网络模型,支持的八种属性与准确率如下:
两个模型均可在intel OpenVINO的官方网站下载即可
代码实现与演示
程序基于OpenVINO的异步推断实现了视频实时的行人检测,在行人检测得到行人ROI的基础上,调用行人属性识别模型实现行人属性识别,输出结果显示。首先需要的是加载模型与读取模型的输入与输出层,这部分的代码实现如下:
# 加载MKLDNN - CPU Target
log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
plugin = IEPlugin(device="CPU", plugin_dirs=plugin_dir)
plugin.add_cpu_extension(cpu_extension)
lut = [];
lut.append((0, 0, 255))
lut.append((255, 0, 0))
lut.append((0, 255, 0))
lut.append((0, 255, 255))
lut.append((255, 0, 255))
# 加载IR
log.info("Reading IR...")
net = IENetwork(model=model_xml, weights=model_bin)
pedestrian_attr_net = IENetwork(model=attribute_xml, weights=attribute_bin)
if plugin.device == "CPU":
supported_layers = plugin.get_supported_layers(net)
not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
if len(not_supported_layers) != 0:
log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
format(plugin.device, ', '.join(not_supported_layers)))
log.error("Please try to specify cpu extensions library path in demo's command line parameters using -l "
"or --cpu_extension command line argument")
sys.exit(1)
assert len(net.inputs.keys()) == 1, "Demo supports only single input topologies"
assert len(net.outputs) == 1, "Demo supports only single output topologies"
# 获取输入输出层
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
lm_input_blob = next(iter(pedestrian_attr_net.inputs))
lm_output_blob = next(iter(pedestrian_attr_net.outputs))
log.info("Loading IR to the plugin...")
# 创建可执行网络
exec_net = plugin.load(network=net, num_requests=2)
lm_exec_net = plugin.load(network=pedestrian_attr_net)
n, c, h, w = net.inputs[input_blob].shape
del net
# we did not need pedestrian model any more
mn, mc, mh, mw = pedestrian_attr_net.inputs[lm_input_blob].shape
del pedestrian_attr_net
读取视频帧实现对每帧图像的行人检测与属性识别的代码如下:
# 开始检测
while cap.isOpened():
if is_async_mode:
ret, next_frame = cap.read()
else:
ret, frame = cap.read()
if not ret:
break
# next_frame = cv2.flip(next_frame, 1)
# 开启同步或者异步执行模式
inf_start = time.time()
if is_async_mode:
in_frame = cv2.resize(next_frame, (w, h))
in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW
in_frame = in_frame.reshape((n, c, h, w))
exec_net.start_async(request_id=next_request_id, inputs={input_blob: in_frame})
else:
in_frame = cv2.resize(frame, (w, h))
in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW
in_frame = in_frame.reshape((n, c, h, w))
exec_net.start_async(request_id=cur_request_id, inputs={input_blob: in_frame})
if exec_net.requests[cur_request_id].wait(-1) == 0:
# 解析DetectionOut
res = exec_net.requests[cur_request_id].outputs[out_blob]
for obj in res[0][0]:
# Draw only objects when probability more than specified threshold
if obj[2] > 0.5:
xmin = int(obj[3] * initial_w)
ymin = int(obj[4] * initial_h)
xmax = int(obj[5] * initial_w)
ymax = int(obj[6] * initial_h)
class_id = int(obj[1])
# Draw box and label\class_id
cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 0, 255), 2)
if xmin > 0 and ymin > 0 and (xmax < initial_w) and (ymax < initial_h):
roi = frame[ymin:ymax, xmin:xmax, :]
pedestrian_roi = cv2.resize(roi, (mw, mh))
pedestrian_roi = pedestrian_roi.transpose((2, 0, 1))
pedestrian_roi = pedestrian_roi.reshape((mn, mc, mh, mw))
# 行人属性识别
lm_exec_net.infer(inputs={'0': pedestrian_roi})
attr_res = lm_exec_net.requests[0].outputs[lm_output_blob]
attr_res = np.reshape(attr_res, (8, 1))
# 解析行人八个属性指标
for i in range(len(attrs)):
if attr_res[i][0] > 0.5:
cv2.putText(frame, attrs[i] + ": " + str(1),
(xmin+30, ymin+20*i),
cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)
else:
cv2.putText(frame, attrs[i] + ": " + str(0),
(xmin + 30, ymin + 20 * i),
cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)
cv2.putText(frame, "Person" + ' ' + str(round(obj[2] * 100, 1)) + ' %', (xmin, ymin - 7),
cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 0, 0), 1)
cv2.imwrite("D:/reslut.png", frame)
inf_end = time.time()
det_time = inf_end - inf_start
# 显示绘制文本
inf_time_message = "Inference time: {:.3f} ms, FPS:{:.3f}".format(det_time * 1000, 1000 / (det_time * 1000 + 1))
render_time_message = "OpenCV rendering time: {:.3f} ms".format(render_time * 1000)
async_mode_message = "Async mode is on. Processing request {}".format(cur_request_id) if is_async_mode else \
"Async mode is off. Processing request {}".format(cur_request_id)
cv2.putText(frame, inf_time_message, (15, 15), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 0), 1)
cv2.putText(frame, render_time_message, (15, 30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (10, 10, 200), 1)
cv2.putText(frame, async_mode_message, (10, int(initial_h - 20)), cv2.FONT_HERSHEY_COMPLEX, 0.5,
(10, 10, 200), 1)
# 显示
render_start = time.time()
cv2.imshow("OpenVINO-face-landmark-detection@57558865", frame)
render_end = time.time()
render_time = render_end - render_start
# ready for next frame
if is_async_mode:
cur_request_id, next_request_id = next_request_id, cur_request_id
frame = next_frame
key = cv2.waitKey(50)
if key == 27:
break
使用两段视频测试截图分别如下:
往期精选
告诉大家你 在看
扫码查看OpenVINO视频教程