CPU上跑深度学习模型,FPS也可以达100帧

2019-11-11 13:28:58 浏览数 (1)

英特尔从去年推出OpenVINO开发框架,从此以后几乎每三个月就更新一个版本,最新版本2019R03,但是此版本跟之前的版本改动比较大,所以在配置Python SDK支持与开发API层面跟之前都有所不同。这里假设你已经正确安装好OpenVINO框架。如果不知道如何安装与配置OpenVINO可以看我在B站视频教程

https://www.bilibili.com/video/av71979782

Python语言支持

01

OpenVINO支持的Python版本SDK与系统列表如下:

首先需要配置好OpenVINO的python SDK支持,这个步骤其实很简单,只需要把安装好的OpenVINO目录下:

代码语言:javascript复制
openvino_2019.3.334pythonpython3.6

下的openvino文件夹copy到安装好的python3.6.5的 site-packages 目录下面,然后就可以正常使用啦。注意,上述的配置方式只对Windows下面有效。

推理引擎SDK API

02

API函数列表与说明

其中最重要的是IECore与IENetwork。

在Python语言中导入SDK支持的python代码如下:

代码语言:javascript复制
from openvino.inference_engine import IENetwork, IECore

初始化IE(inference Engine)插件,查询设备支持的代码如下:

代码语言:javascript复制
ie = IECore()
for device in ie.available_devices:
         print("Device: {}".format(device))

执行结果截图如下:

可以看到,在我的电脑上支持的设备还是挺多的,计算棒支持没问题!

在通过ie创建可执行网络的时候,会需要你指定可执行网络运行的目标设备。我们就可以从上述支持的设备中选择支持。这里需要注意的是CPU需要扩展支持,添加扩展支持的代码如下:

代码语言:javascript复制
ie.add_extension(cpu_extension, "CPU")

创建可执行的网络的代码如下:

代码语言:javascript复制
# CPU 执行
exec_net = ie.load_network(network=net, device_name="CPU", num_requests=2)
# 计算棒执行
lm_exec_net = ie.load_network(network=landmark_net, device_name="MYRIAD")

这里我们创建了两个可执行网络,两个深度学习模型分别在CPU与计算棒上执行推理,其中第一个可执行网络的推理请求数目是2个,执行异步推理。

人脸检测演示

03

基于OpenVINO的人脸检测模型与landmark检测模型,实现了一个CPU级别高实时人脸检测与landmark提取的程序,完整的代码实现如下:

代码语言:javascript复制
def face_landmark_demo():
    # query device support
    ie = IECore()
    for device in ie.available_devices:
        print("Device: {}".format(device))
    ie.add_extension(cpu_extension, "CPU")

    # LUT
    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))


    # Read IR
    log.info("Reading IR...")
    net = IENetwork(model=model_xml, weights=model_bin)
    landmark_net = IENetwork(model=landmark_xml, weights=landmark_bin)


    # 获取输入输出
    input_blob = next(iter(net.inputs))
    out_blob = next(iter(net.outputs))

    lm_input_blob = next(iter(landmark_net.inputs))
    lm_output_blob = next(iter(landmark_net.outputs))

    log.info("create exec network with target device...")
    exec_net = ie.load_network(network=net, device_name="CPU", num_requests=2)
    lm_exec_net = ie.load_network(network=landmark_net, device_name="MYRIAD")
    # Read and pre-process input image
    n, c, h, w = net.inputs[input_blob].shape
    mn, mc, mh, mw = landmark_net.inputs[lm_input_blob].shape

    # 释放网络
    del net
    del landmark_net

    cap = cv2.VideoCapture("D:/images/video/SungEun.avi")

    cur_request_id = 0
    next_request_id = 1

    log.info("Starting inference in async mode...")
    log.info("To switch between sync and async modes press Tab button")
    log.info("To stop the demo execution press Esc button")
    is_async_mode = True
    render_time = 0
    ret, frame = cap.read()

    print("To close the application, press 'CTRL C' or any key with focus on the output window")
    while cap.isOpened():
        if is_async_mode:
            ret, next_frame = cap.read()
        else:
            ret, frame = cap.read()
        if not ret:
            break
        initial_w = cap.get(3)
        initial_h = cap.get(4)

        # 开启同步或者异步执行模式
        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:
            # 获取网络输出
            res = exec_net.requests[cur_request_id].outputs[out_blob]

            # 解析DetectionOut
            for obj in res[0][0]:
                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)
                    if xmin > 0 and ymin > 0 and (xmax < initial_w) and (ymax < initial_h):
                        roi = frame[ymin:ymax,xmin:xmax,:]
                        rh, rw = roi.shape[:2]
                        face_roi = cv2.resize(roi, (mw, mh))
                        face_roi = face_roi.transpose((2, 0, 1))
                        face_roi = face_roi.reshape((mn, mc, mh, mw))
                        lm_exec_net.infer(inputs={'0':face_roi})
                        landmark_res = lm_exec_net.requests[0].outputs[lm_output_blob]
                        landmark_res = np.reshape(landmark_res, (5, 2))
                        for m in range(len(landmark_res)):
                            x = landmark_res[m][0] * rw
                            y = landmark_res[m][1] * rh
                            cv2.circle(roi, (np.int32(x), np.int32(y)), 3, lut[m], 2, 8, 0)
                    cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 0, 255), 2, 8, 0)

            inf_end = time.time()
            det_time = inf_end - inf_start
            # Draw performance stats
            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, (200, 10, 10), 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("face detection", frame)
        render_end = time.time()
        render_time = render_end - render_start

        if is_async_mode:
            cur_request_id, next_request_id = next_request_id, cur_request_id
            frame = next_frame

        key = cv2.waitKey(1)
        if key == 27:
            break

    cv2.waitKey(0)
    # 释放资源
    cv2.destroyAllWindows()
    del exec_net
    del lm_exec_net
    del ie

1920x1080大小的视频画面检测,超高实时无压力!有图为证:

0 人点赞