openvino yoloface4点模型部署

前言:

首先感谢大佬的开源代码

GitHub - fb029ed/yolov5_cpp_openvino: 用c++实现了yolov5使用openvino的部署

以及他写的原版yolov5部署代码

C++实现yolov5的OpenVINO部署_Tom Hardy的博客-CSDN博客

接下来我要在他的代码的基础上,部署yoloface四点模型代码

一、项目介绍:

在大佬原版的模型中,输出为1*3*20*20*85(其中一个detect的输出,剩下两个的20分别变为40和80。)这里85=conf(1)+xywh(4)+cls(80)

 而我训练的模型,输出为1*3*20*20*30,30=conf(1)+xywh(4)+point(2*4)+cls(17)。共4个关键点,17个类。

二、灰度填充

由于我的训练模型对长宽比有着较高的要求,所以对图片预处理时,不能直接resize,而要进行灰度填充。

2.1 python源码:

def letterbox(img, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True): #yoloface    # Resize image to a 32-pixel-multiple rectangle https://github.com/ultralytics/yolov3/issues/232    shape = img.shape[:2]  # current shape [height, width]    if isinstance(new_shape, int):        new_shape = (new_shape, new_shape)    # Scale ratio (new / old)    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])    if not scaleup:  # only scale down, do not scale up (for better test mAP)        r = min(r, 1.0)    # Compute padding    ratio = r, r  # width, height ratios    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding    if auto:  # minimum rectangle        dw, dh = np.mod(dw, 64), np.mod(dh, 64)  # wh padding    elif scaleFill:  # stretch        dw, dh = 0.0, 0.0        new_unpad = (new_shape[1], new_shape[0])        ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios    dw /= 2  # divide padding into 2 sides    dh /= 2    if shape[::-1] != new_unpad:  # resize        img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))    img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border    return img, ratio, (dw, dh)

2.2 代码改写(Mat不需要在.h中单独声明)

我要将改写的C++代码写到了类Detector里。这个代码传入的参数有Mat类型。因此,我在头文件中进行如下声明

    void letterbox(Mat& inframe,Mat& outframe,int x_size,int y_size);

在.cpp文件中如下实现

void Detector::letterbox(Mat& inframe,Mat& outframe,int x_size,int y_size) //定义一个用于将图片填充成正方形的函数 参数:(输入图像,输出图像){    int x_ori = inframe.cols;  //得到图片宽度    int y_ori = inframe.rows;  //得到图片高度    cout<<"宽:"<<x_ori<<endl;    cout<<"高:"<<y_ori<<endl;        float r_x = (double)x_ori/x_size; // 1280/640    float r_y = (double)y_ori/y_size; // 1024/640 确定缩放比,后图除以原图,值比较大(缩放没那么严重的)那个方向要padding(来多缩放些)    if(r_x >= r_y) // 在上下方向填充 那么y的理论高度应该是x_ori/x_size*y_size    {      int y0 = y_size * x_ori / x_size;      int y_pad = (y0 - y_ori)/2;        cv::copyMakeBorder(inframe,inframe,y_pad,y_pad,0,0, cv::BORDER_CONSTANT,20);    }    else // 在上下方向填充 那么y的理论高度应该是x_ori/x_size*y_size    {        int x0 = x_size * y_ori / y_size;        int x_pad = (x0 - x_ori)/2;        cv::copyMakeBorder(inframe,inframe,0,0,x_pad,x_pad, cv::BORDER_CONSTANT,20);    }}

在函数中如下调用

    letterbox(inframe,inframe,640,640);

2.3 难点 如下函数如何填充灰色?(最后一个参数输入value只会有一个通道有颜色)

2.4 疑惑:为什么我在main函数无法调用detector->lettorbox,得到osrc?(不报错,但是并没有返回osrc)

    Mat osrc ;    detector->letterbox(src,osrc,640,640);

原因:之前声明和定义时没有用&,不用这个就不会传递参数!

2.5 注意:tensor前面的是图片高度,后面是图片宽度

2.6 重点(坑了我一整天):

    int s[3] = {40,20,80};   

这一层detect探头的顺序是40,20,80,不是这个顺序的话,输出的结果不但是错误的,而且有2-3种不同的错误结果,每次运行不一样,不知道为什么错误结果还不同。

2.7 关于vector

一定要分清vector和他存储的元素。头文件没有单独定义vector,但是在声明函数的时候变量处要写vector,而且要加&,如下

    bool parse_yolov5(const Blob::Ptr &blob,int net_grid,float cof_threshold,        vector<Rect>& o_rect,vector<float>& o_rect_cof,vector<Four_point>& point_list);

2.8 遇到问题:输出结果如下

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ZWc6Iqx5rC05pyI55CJ55KD55uP,size_7,color_FFFFFF,t_70,g_se,x_16

 框没有问题,但是点非常的狂放不羁。

原因:

                four_Point.cls = cls_id;                four_Point.x1 = x1 * anchors[n * 2] + j * 640.0f / net_grid;                four_Point.y1 = y1 * anchors[n * 2 + 1] + i * 640.0f / net_grid;                four_Point.x2 = x2 * anchors[n * 2] + j * 640.0f / net_grid;                four_Point.y2 = y2 * anchors[n * 2 + 1] + i * 640.0f / net_grid;                four_Point.x3 = x3 * anchors[n * 2] + j * 640.0f / net_grid;                four_Point.y3 = y3 * anchors[n * 2 + 1] + i * 640.0f / net_grid;                four_Point.x4 = x4 * anchors[n * 2] + j * 640.0f / net_grid;                four_Point.y4 = y4 * anchors[n * 2 + 1] + i * 640.0f / net_grid;

上面这段代码我无意中多加了个括号,导致差距被放大了16倍。

猜你喜欢

转载自blog.csdn.net/m0_58348465/article/details/122707931