Cpp DenseNet OpenVino测试

Cpp OpenVino测试

Python版本导引

模型测试

跟前篇文章一致Cpp DenseNet OpenVino导出,
我们仍然需要在Python的开发流程中完成导出以及测试,如果看过本人文章的Python版本,可以跳过

下面将要介绍CPP版本如何配置OpenVINO,这里需要简单说明一下,CPP版本的OpenVINO需要和Python版本几乎一致,这里的OpenVINO使用pip安装,成功率最高的方式,应该使用OpenVINO SDK里面的whl包进行安装

# https://docs.openvino.ai/2024/notebooks/vision-monodepth-with-output.html
# https://colab.research.google.com/github/openvinotoolkit/openvino_notebooks/blob/latest/notebooks/vision-monodepth/vision-monodepth.ipynb#scrollTo=1c9f693b
import time

import openvino as ov
import cv2
import numpy
import torch
import torch.nn as nn
from torchvision import models
from torch.nn import functional as F
from torchvision.transforms import transforms


def get_kernel(kernel_len=16, nsig=10):  # nsig 标准差 ,kernlen=16核尺寸
    GaussianKernel = cv2.getGaussianKernel(kernel_len, nsig) \
                     * cv2.getGaussianKernel(kernel_len, nsig).T
    return GaussianKernel


class Gaussian_kernel(nn.Module):
    def __init__(self,
                 kernel_len, nsig=20):
        super(Gaussian_kernel, self).__init__()
        self.kernel_len = kernel_len
        kernel = get_kernel(kernel_len=kernel_len, nsig=nsig)  # 获得高斯卷积核
        kernel = torch.FloatTensor(kernel).unsqueeze(0).unsqueeze(0)  # 扩展两个维度
        self.weight = nn.Parameter(data=kernel, requires_grad=False)

        self.padding = torch.nn.ReplicationPad2d(int(self.kernel_len / 2))

    def forward(self, x):  # x1是用来计算attention的,x2是用来计算的Cs
        x = self.padding(x)
        # 对三个channel分别做卷积
        res = []
        for i in range(x.shape[1]):
            res.append(F.conv2d(x[:, i, :, :], self.weight))
        x_output = torch.cat(res, dim=0)
        return x_output


class DensenetGrade:
    def __init__(self, pth_path: str):
        core = ov.Core()
        cpu_model = core.read_model(pth_path)
        self.model = core.compile_model(model=cpu_model, device_name="CPU")
        self.output_key = self.model.output(0)

        self.result_name = "Densenet121Grade"

        self.gaussian_kernel = Gaussian_kernel(11, 30)
        self.transform_kernel = transforms.Compose([
            transforms.ToTensor()
        ])

    def softmax(self, x):
        f_x = numpy.exp(x) / numpy.sum(numpy.exp(x))
        return f_x

    @torch.no_grad()
    def infer(self, image_path: str):
        trans_dim = self._preprocess(image_path)
        result = self.model([trans_dim.numpy()])[self.output_key]
        y = self.softmax(result[0]).tolist()
        return self._postprocess(y)

    def _postprocess(self, pred_arr):
        return {
            'index': pred_arr.index(max(pred_arr)),
            'pie': pred_arr
        }

    def _preprocess(self, data_in: str):
        img_arr = self.circle_crop(data_in) / 255.0
        x = torch.from_numpy(img_arr[:, :, ::-1].astype(numpy.float32).transpose((2, 0, 1))).unsqueeze(0)
        return x

    def circle_crop(self, image_src: str):
        crop_mask = self.crop_image_from_mask(image_src)
        return self.crop_image_with_gaussian(crop_mask)

    def crop_image_from_mask(self, image_src: str):
        # load
        image = cv2.imread(image_src)

        # binary
        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        _, binary_image = cv2.threshold(gray_image, 7, 255, cv2.THRESH_BINARY)

        # cal roi
        x, y, w, h = cv2.boundingRect(binary_image)
        center = (w // 2), (h // 2)
        radius = min(center)
        y = y + center[1] - radius
        x = x + center[0] - radius
        copy_image = image[y: y + 2 * radius, x: x + 2 * radius]

        # gen mask
        mask = numpy.zeros_like(copy_image)
        cv2.circle(mask, (radius, radius), radius, (1, 1, 1), -1)

        # exposure
        return copy_image * mask

    def crop_image_with_gaussian(self, data_in: numpy.ndarray):
        ori_image = cv2.resize(data_in, (224, 224)).astype(numpy.float32)
        with torch.no_grad():
            image_cuda = self.transform_kernel(ori_image).unsqueeze(0)
            out = numpy.transpose(self.gaussian_kernel(image_cuda).cpu().numpy(), (1, 2, 0))

        if out.shape != (224, 224, 3):
            out = out[0: 224, 0: 224]
        exposure = cv2.addWeighted(ori_image, 4, out, -4, 128)
        exposure = numpy.clip(exposure, 0, 255).astype(numpy.uint8)
        exposure = cv2.cvtColor(exposure, cv2.COLOR_BGR2RGB)
        return exposure


if __name__ == '__main__':
    # fp32 {'index': 2, 'pie': [0.1433304101228714, 0.05587254837155342, 0.7058674693107605, 0.08943081647157669, 0.0054987091571092606]}
    grade = DensenetGrade("export_dense121_cpu.xml")
    t1 = time.perf_counter()
    print(grade.infer("1.jpg"))
    t2 = time.perf_counter()
    print(t2 - t1)
    # cv2.imwrite("2-1.jpg", grade.crop_image_from_mask("1-1.jpg"))
    # cv2.imwrite("2-2.jpg",  grade.circle_crop("1-1.jpg"))
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenVINO是Intel开发的基于Intel设备的推理引擎,可以利用CPU发挥最好的性能,还能使用到新款CPU所提供的NN算力。下面是OpenVINO推理的一些步骤和方法: 1. 首先,需要将模型转换为OpenVINO支持的IR格式。可以使用OpenVINO提供的Model Optimizer工具进行转换。 2. 接下来,需要加载IR模型并创建推理引擎。可以使用Inference Engine API来完成这些操作。 3. 在创建推理引擎后,需要创建推理请求并设置输入数据。可以使用Inference Engine API中的InferRequest类来完成这些操作。 4. 推理请求创建完成后,可以使用InferRequest类的Infer()方法来执行推理操作。 下面是一个使用OpenVINO进行推理的C++代码示例: ```cpp #include <inference_engine.hpp> using namespace InferenceEngine; int main() { // 加载IR模型并创建推理引擎 Core core; CNNNetwork network = core.ReadNetwork("model.xml", "model.bin"); ExecutableNetwork executable_network = core.LoadNetwork(network, "CPU"); // 创建推理请求并设置输入数据 InferRequest infer_request = executable_network.CreateInferRequest(); Blob::Ptr input_blob = infer_request.GetBlob("input"); float* input_data = input_blob->buffer().as<float*>(); // 设置输入数据 // ... // 执行推理操作 infer_request.Infer(); // 获取输出数据 Blob::Ptr output_blob = infer_request.GetBlob("output"); float* output_data = output_blob->buffer().as<float*>(); // 处理输出数据 // ... return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值