基于OpenVINO™2022.1C++API部署YOLOv7预训练模型|开发者实战

OpenCV学堂 2022-09-05 21:40

点击上方↑↑↑OpenCV学堂”关注我

来源:公众号 英特尔物联网 授权


文章作者

英特尔AI高级工程师

杨亦诚



毕业于约克大学电子工程系,深度学习解决方案专家。致力于边缘智能生态推广,拥有多年人工智能应用开发与项目落地经验。 


任务背景 


作为视觉应用中最常见的任务之一,目标检测一直是各类新模型刷榜的必争之地,其中就以 YOLO 系列的网络结构最为突出。YOLO 的全称是 you only look once,指只通过 one-stage 的方式需要“浏览一次”就可以识别出图中的物体的类别和位置。近期YOLO官方团队又放出新版本——YOLOv7,速度、精度都超越其他变体。本文将分享如何基于 OpenVINO 2022.1工具套件部署 YOLOv7 官方提供的预训练模型。附 C++/Python 源码及使用方法。


代码仓库地址:

https://github.com/OpenVINO-dev-contest/YOLOv7_OpenVINO_cpp-python

OpenVINO 简介 


用于高性能深度学习的英特尔发行版 OpenVINO™ 工具套件基于 oneAPI 而开发,以期在从边缘到云的各种英特尔平台上,帮助用户更快地将更准确的真实世界结果部署到生产系统中。通过简化的开发工作流程,OpenVINO™ 可赋能开发者在现实世界中部署高性能应用程序和算法。


在推理后端,得益于 OpenVINO 工具套件提供的“一次编写,随处部署”特性,转换后的模型能够在不同的英特尔硬件平台上运行,无需重新构建,有效简化了构建与迁移过程。此外,为了支持更多的异构加速单元,OpenVINO™ 的 runtime api 底层采用了插件式的开发架构,基于oneAPI 中的 MKL-DNN、oneDNN 等函数计算加速库,针对 AVX-512 等通用指令集进行优化,为不同的硬件执行单元分别实现了一套完整的高性能算子库,提升模型在推理运行时的整体性能表现。

YOLOv7 简介


官方版的 YOLOv7 相同体量下比 YOLOv5 精度更高,速度快120%(FPS),比 YOLOX 快180%(FPS),比 Dual-Swin-T 快1200%(FPS),比 ConvNext 快550%(FPS),比 SWIN-L快500%(FPS)。在5FPS 到160FPS 的范围内,无论是速度或是精度,YOLOv7 都超过了目前已知的检测器,并且在GPU V100 上进行测试, 精度为56.8% AP的模型可达到30 FPS(batch=1)以上的检测速率,与此同时,这是目前唯一一款在如此高精度下仍能超过 30FPS 的检测器。

任务开发流程


我们先整体来看下 YOLOv7 的输入输出结构,首先对输入的图片 resize 为 640x640 大小,输入到 backbone 网络中,得到三层不同 size 大小的 feature map,并输出对应预测结果,这里以 coco 数据集为例子,输出为 80 个类别,然后每个输出(x ,y, w, h, o) 即坐标位置和是否存在物体的置信度,3 是指的 anchor 数量,因此每一层的输出为 (80+5) x 3 = 255再乘上 feature map 的大小就是最终的输出了。整个开发流程可以分为数据处理模块定义、前处理任务、推理任务、后处理任务四部分组成。


图:YOLOv7官方预训练模型的输入输出结构


1. 数据处理模块


定义 Object 结构体用来存放模型的输出数据,包含  bounding box 信息,类别标签,以及是否存在物体和类别的累计置信度。


定义 class_names 向量,用于存放 coco 数据集的所有标签。

struct Object{    cv::Rect_ rect;    int label;    float prob;};
const std::vector class_names = {    "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",    "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",    "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",    "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",    "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",    "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",    "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone",    "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear",    "hair drier", "toothbrush"};

定义 letterbox 与 scale_box 模块,分别用于在图像前处理任务中为输入数据添加 letterbox,以及在后处理任务还原 letterbox 带来坐标位置变换。这里特别值得注意的是我们增加了一个 padd 向量,用于存放在添加 letterbox 过程中 letterbox 的 size 信息以及相较原始图片的缩放比例信息,该组数据会用于在后处理任务中还原删除 letterbox 以后的结果。

cv::Mat letterbox(cv::Mat &src, int h, int w, std::vector &padd){    // Resize and pad image while meeting stride-multiple constraints    int in_w = src.cols;    int in_h = src.rows;    int tar_w = w;    int tar_h = h;    float r = min(float(tar_h) / in_h, float(tar_w) / in_w);    int inside_w = round(in_w * r);    int inside_h = round(in_h * r);    int padd_w = tar_w - inside_w;    int padd_h = tar_h - inside_h;    cv::Mat resize_img;
   // resize    resize(src, resize_img, cv::Size(inside_w, inside_h));
   // divide padding into 2 sides    padd_w = padd_w / 2;    padd_h = padd_h / 2;    padd.push_back(padd_w);    padd.push_back(padd_h);
   // store the ratio    padd.push_back(r);    int top = int(round(padd_h - 0.1));    int bottom = int(round(padd_h + 0.1));    int left = int(round(padd_w - 0.1));    int right = int(round(padd_w + 0.1));
   // add border    copyMakeBorder(resize_img, resize_img, top, bottom, left, right, 0, cv::Scalar(114, 114, 114));    return resize_img;}
cv::Rect scale_box(cv::Rect box, std::vector &padd){      // remove the padding area    cv::Rect scaled_box;    scaled_box.x = box.x - padd[0];    scaled_box.y = box.y - padd[1];    scaled_box.width = box.width;    scaled_box.height = box.height;    return scaled_box;}

定义 generate_proposal 模块,该模块具体有以下几个功能:

01

根据定义的 anchors,在输入图像中生成各类 feature map 的候选框;

02

根据输出结果调整候选框位置和大小,并将其作为 bounding box 还原到输入图像的坐标系中;

03

过滤置信度较低的分类结果,获取类别结果。

static void generate_proposals(int stride, const float *feat, float prob_threshold, std::vector &objects){       // get the results from proposals    float anchors[18] = {12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401};    int anchor_num = 3;    int feat_w = 640 / stride;    int feat_h = 640 / stride;    int cls_num = 80;    int anchor_group = 0;    if (stride == 8)        anchor_group = 0;    if (stride == 16)        anchor_group = 1;    if (stride == 32)        anchor_group = 2;
   // 3 x h x w x (80 + 5)    for (int anchor = 0; anchor <= anchor_num - 1; anchor++)    {        for (int i = 0; i <= feat_h - 1; i++)        {            for (int j = 0; j <= feat_w - 1; j++)            {                float box_prob = feat[anchor * feat_h * feat_w * (cls_num + 5) + i * feat_w * (cls_num + 5) + j * (cls_num + 5) + 4];                box_prob = sigmoid(box_prob);
               // filter the bounding box with low confidence                if (box_prob < prob_threshold)                    continue;                float x = feat[anchor * feat_h * feat_w * (cls_num + 5) + i * feat_w * (cls_num + 5) + j * (cls_num + 5) + 0];                float y = feat[anchor * feat_h * feat_w * (cls_num + 5) + i * feat_w * (cls_num + 5) + j * (cls_num + 5) + 1];                float w = feat[anchor * feat_h * feat_w * (cls_num + 5) + i * feat_w * (cls_num + 5) + j * (cls_num + 5) + 2];                float h = feat[anchor * feat_h * feat_w * (cls_num + 5) + i * feat_w * (cls_num + 5) + j * (cls_num + 5) + 3];
               double max_prob = 0;                int idx = 0;
               // get the class id with maximum confidence                for (int t = 5; t < 85; ++t)                {                    double tp = feat[anchor * feat_h * feat_w * (cls_num + 5) + i * feat_w * (cls_num + 5) + j * (cls_num + 5) + t];                    tp = sigmoid(tp);                    if (tp > max_prob)                    {                        max_prob = tp;                        idx = t;                    }                }
               // filter the class with low confidence                float cof = box_prob * max_prob;                if (cof < prob_threshold)                    continue;                                // convert results to xywh                x = (sigmoid(x) * 2 - 0.5 + j) * stride;                y = (sigmoid(y) * 2 - 0.5 + i) * stride;                w = pow(sigmoid(w) * 2, 2) * anchors[anchor_group * 6 + anchor * 2];                h = pow(sigmoid(h) * 2, 2) * anchors[anchor_group * 6 + anchor * 2 + 1];
               float r_x = x - w / 2;                float r_y = y - h / 2;
               // store the results                Object obj;                obj.rect.x = r_x;                obj.rect.y = r_y;                obj.rect.width = w;                obj.rect.height = h;                obj.label = idx - 5;                obj.prob = cof;                objects.push_back(obj);            }        }    }}


2. 前处理任务


前处理主要包含以下几个步骤:


01

使用 OpenCV 读取图片文件

02

对于原始图片进行 resize 并添加 letterbox

03

将色彩通道从 BGR 转化为 RGB

04

将输入数据进行 layout 转置(NHWC

=>NCHW), 与归一化操作(见模型推理部分代码)

cv::Mat src_img = cv::imread(image_path);    cv::Mat img;
   std::vector padd;    cv::Mat boxed = letterbox(src_img, img_h, img_w, padd);    cv::cvtColor(boxed, img, cv::COLOR_BGR2RGB);


3. 推理任务


图:OpenVINO 工具套件 runtime 开发流程


模型推理部分主要调用 OpenVINO™ 的 C++ API 进行实现,OpenVINO™ 推理接口的调用流程如上图所示

可参考官方说明:

https://docs.openvino.ai/latest/openvino_docs_OV_UG_Integrate_OV_with_your_application.html


在这里第2步 Complie Model 亦可分为模型读取与模型编译两个步骤执行,同时可以发现相较2021.4之前的版本,OpenVINO 2022.1在输入以及输出数据的接口调用方式上有了极大的简化,可以通过 Tensor 相关的构造函数,轻松实现模型数据的载入和读取。在整个过程中开发者需要将输入数据进行layout转置(NHWC=>NCHW),并填充到 input tensor 所对应的数据指针地址中。在结果数据提取部分,由于该模型有3个不同尺度 feature map output,因此我们需要逐一获取他们结果数据指针。

// -------- Step 1. Initialize OpenVINO Runtime Core --------    ov::Core core;
   // -------- Step 2. Read a model --------    std::shared_ptr model = core.read_model(model_path);
   // -------- Step 3. Loading a model to the device --------    ov::CompiledModel compiled_model = core.compile_model(model, device_name);
   // Get input port for model with one input    auto input_port = compiled_model.input();    // Create tensor from external memory    // ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), input_data.data());    // -------- Step 4. Create an infer request --------    ov::InferRequest infer_request = compiled_model.create_infer_request();
   // -------- Step 5. Prepare input --------    ov::Tensor input_tensor1 = infer_request.get_input_tensor(0);    // NHWC => NCHW    auto data1 = input_tensor1.data();    for (int h = 0; h < img_h; h++)    {        for (int w = 0; w < img_w; w++)        {            for (int c = 0; c < 3; c++)            {                // int in_index = h * img_w * 3 + w * 3 + c;                int out_index = c * img_h * img_w + h * img_w + w;                data1[out_index] = float(img.at(h, w)[c]) / 255.0f;            }        }    }
   // -------- Step 6. Start inference --------    infer_request.infer();
   // -------- Step 7. Process output --------    auto output_tensor_p8 = infer_request.get_output_tensor(0);    const float *result_p8 = output_tensor_p8.data();    auto output_tensor_p16 = infer_request.get_output_tensor(1);    const float *result_p16 = output_tensor_p16.data();    auto output_tensor_p32 = infer_request.get_output_tensor(2);    const float *result_p32 = output_tensor_p32.data();


4. 后处理任务


后处理部分需要调用我们之前定义的 generate_proposals 用于还原每一个 feature map 的结果数据,并进行堆叠,最后使用 OpenCV DNN 模块中自带的 NMS 方法,完成对结果 bounding box 的非极大抑制过滤,获取我们在原始 input image 中的目标位置与类别信息。

 generate_proposals(8, result_p8, prob_threshold, objects8);    proposals.insert(proposals.end(), objects8.begin(), objects8.end());    generate_proposals(16, result_p16, prob_threshold, objects16);    proposals.insert(proposals.end(), objects16.begin(), objects16.end());    generate_proposals(32, result_p32, prob_threshold, objects32);    proposals.insert(proposals.end(), objects32.begin(), objects32.end());
   std::vector classIds;    std::vector confidences;    std::vector boxes;
   for (size_t i = 0; i < proposals.size(); i++)    {        classIds.push_back(proposals[i].label);        confidences.push_back(proposals[i].prob);        boxes.push_back(proposals[i].rect);    }
   std::vector picked;
   // do non maximum suppression for each bounding boxx    cv::dnn::NMSBoxes(boxes, confidences, prob_threshold, nms_threshold, picked);

此外,我们还需要进一步调整模型 input data 对应的结果数据,将其还原到原始尺寸的图片上进行展示。

 int idx = picked[i];        cv::Rect box = boxes[idx];        cv::Rect scaled_box = scale_box(box, padd);        drawPred(classIds[idx], confidences[idx], scaled_box, padd[2], raw_h, raw_w, src_img, class_names);

参考示例使用方法


该示例分别提供了 C++和 Python 的参考实现,具体使用方法如下:


1. 依赖安装

# 下载示例仓库$ git clone https://github.com/OpenVINO-dev-contest/YOLOv7_OpenVINO_cpp-python.git


C++ 环境依赖



由于本示例的 C++ 版本只依赖OpenVINO 和OpenCV 的运行库,所以需要开发者提前完成对这两个工具组件的安装:


OpenVINO C++ runtime 安装地址:

https://docs.openvino.ai/latest/openvino_docs_install_guides_installing_openvino_linux.html#install-openvino


OpenCV 环境安装地址:

https://docs.opencv.org/4.x/d7/d9f/tutorial_linux_install.html


注:由于该示例中提供的 CMakeList 使用 OpenCV 的默认路径,因此需要在完成 OpenCV 的编译后,执行 make install 命令。


Python 环境依赖



Python 环境的安装相对简单,只需通过 pip 命令行工具进行依赖安装:

$ pip install -r python/requirements


2. 预训练模型下载


可以从官方 github 仓库提供的链接中下载基于 COCO 数据集的 YOLOv7 预训练模型权重:

https://github.com/WongKinYiu/yolov7



3. 模型转换


目前 OpenVINO  runtime 可以直接支持 onnx 格式的模型部署,所以我们在得到.pt权重文件后,只需使用官方自带 export.py 脚本,就可将其导出为 onnx 格式模型,具体过程如下:

# 下载YOLOv7官方仓库:$ git clone git@github.com:WongKinYiu/yolov7.git$ cd yolov7/models$ python export.py --weights yolov7.pt


4. 测试运行


C++ 示例



编译 C++ 示例源码,编译完成后会在 build 目录下生成 YOLOv7 可执行文件:

  $ cd cpp  $ mkdir build && cd build  $ source '~/intel/openvino_2022.1.0.643/bin/setupvars.sh'  $ cmake ..  $ make

执行推理任务:

 $ yolov7 yolov7.onnx data/horses.jpg 'CPU'


Python 示例



执行推理任务:

  $ python python/main.py -m yolov7.onnx -i data/horse.jpg


5. 测试结果


运行推理示例后,会在本地目录下生成代 bounding box 以及 label 的图片,这里我们用到官方仓库中附带的马匹数据进行测试,具体结果如下:


图:推理运行结果

Benchmark App 介绍


OpenVINO 提供了性能测试工具 Benchmark App  ,方便开发者快速测试 OpenVINO 模型在不同的硬件平台上的性能。我们以下面的例子,简单介绍 benchmark app 的使用方法和相关参数,更多内容请参考 Benchmark App 官方文档。

$ benchmark_app -m yolov7.onnx  -hint throughput

-m: 指定模型路径。由于目前OpenVINO  runtime是支持直接读取 onnx 格式文件的,所以这里我们设置为导出以后 onnx 模型。


-hint: 指定性能测试的优先策略,以自动选择底层性能优化相关参数。这里我们选择 throughput 模式来提升系统整体吞吐量。如果应用对延迟比较敏感,推荐使用 latency 模式来减少推理延迟。

结论


YOLOv7 由于其出色的精度和性能表现,在推出第一时就受到了极大的关注,目前 github 上的 star 已超过5K。本示例通过OpenVINO 2022.1新版本的 C++ API 接口,实现对 YOLOv7 官方预训练模型的部署。最后使用 OpenVINO自带的 benchmark_app 工具进一步对模型的性能进行验证测试。

参考文献:

YOLOv7官方仓库:

https://github.com/WongKinYiu/yolov7


OpenVINO 开发文档:

https://docs.openvino.ai/latest/openvino_docs_OV_UG_Integrate_OV_with_your_application.html


OpenCV学堂 专注计算机视觉开发技术分享,技术框架使用,包括OpenCV,Tensorflow,Pytorch教程与案例,相关算法详解,最新CV方向论文,硬核代码干货与代码案例详解!作者在CV工程化方面深度耕耘15年,感谢您的关注!
评论
  • 一、VSM的基本原理震动样品磁强计(Vibrating Sample Magnetometer,简称VSM)是一种灵敏且高效的磁性测量仪器。其基本工作原理是利用震动样品在探测线圈中引起的变化磁场来产生感应电压,这个感应电压与样品的磁矩成正比。因此,通过测量这个感应电压,我们就能够精确地确定样品的磁矩。在VSM中,被测量的样品通常被固定在一个震动头上,并以一定的频率和振幅震动。这种震动在探测线圈中引起了变化的磁通量,从而产生了一个交流电信号。这个信号的幅度和样品的磁矩有着直接的关系。因此,通过仔细
    锦正茂科技 2025-02-28 13:30 78浏览
  •           近日受某专业机构邀请,参加了官方举办的《广东省科技创新条例》宣讲会。在与会之前,作为一名技术工作者一直认为技术的法例都是保密和侵权方面的,而潜意识中感觉法律有束缚创新工作的进行可能。通过一个上午学习新法,对广东省的科技创新有了新的认识。广东是改革的前沿阵地,是科技创新的沃土,企业是创新的主要个体。《广东省科技创新条例》是广东省为促进科技创新、推动高质量发展而制定的地方性法规,主要内容包括: 总则:明确立法目
    广州铁金刚 2025-02-28 10:14 90浏览
  • 美国加州CEC能效跟DOE能效有什么区别?CEC/DOE是什么关系?美国加州CEC能效跟DOE能效有什么区别?CEC/DOE是什么关系?‌美国加州CEC能效认证与美国DOE能效认证在多个方面存在显著差异‌。认证范围和适用地区‌CEC能效认证‌:仅适用于在加利福尼亚州销售的电器产品。CEC认证的范围包括制冷设备、房间空调、中央空调、便携式空调、加热器、热水器、游泳池加热器、卫浴配件、光源、应急灯具、交通信号模块、灯具、洗碗机、洗衣机、干衣机、烹饪器具、电机和压缩机、变压器、外置电源、消费类电子设备
    张工nx808593 2025-02-27 18:04 94浏览
  • RGB灯光无法同步?细致的动态光效设定反而成为产品客诉来源!随着科技的进步和消费者需求变化,电脑接口设备单一功能性已无法满足市场需求,因此在产品上增加「动态光效」的形式便应运而生,藉此吸引消费者目光。这种RGB灯光效果,不仅能增强电脑周边产品的视觉吸引力,还能为用户提供个性化的体验,展现独特自我风格。如今,笔记本电脑、键盘、鼠标、鼠标垫、耳机、显示器等多种电脑接口设备多数已配备动态光效。这些设备的灯光效果会随着音乐节奏、游戏情节或使用者的设置而变化。想象一个画面,当一名游戏玩家,按下电源开关,整
    百佳泰测试实验室 2025-02-27 14:15 132浏览
  • 在物联网领域中,无线射频技术作为设备间通信的核心手段,已深度渗透工业自动化、智慧城市及智能家居等多元场景。然而,随着物联网设备接入规模的不断扩大,如何降低运维成本,提升通信数据的传输速度和响应时间,实现更广泛、更稳定的覆盖已成为当前亟待解决的系统性难题。SoC无线收发模块-RFM25A12在此背景下,华普微创新推出了一款高性能、远距离与高性价比的Sub-GHz无线SoC收发模块RFM25A12,旨在提升射频性能以满足行业中日益增长与复杂的设备互联需求。值得一提的是,RFM25A12还支持Wi-S
    华普微HOPERF 2025-02-28 09:06 101浏览
  • 1,微软下载免费Visual Studio Code2,安装C/C++插件,如果无法直接点击下载, 可以选择手动install from VSIX:ms-vscode.cpptools-1.23.6@win32-x64.vsix3,安装C/C++编译器MniGW (MinGW在 Windows 环境下提供类似于 Unix/Linux 环境下的开发工具,使开发者能够轻松地在 Windows 上编写和编译 C、C++ 等程序.)4,C/C++插件扩展设置中添加Include Path 5,
    黎查 2025-02-28 14:39 100浏览
  • 在2024年的科技征程中,具身智能的发展已成为全球关注的焦点。从实验室到现实应用,这一领域正以前所未有的速度推进,改写着人类与机器的互动边界。这一年,我们见证了具身智能技术的突破与变革,它不仅落地各行各业,带来新的机遇,更在深刻影响着我们的生活方式和思维方式。随着相关技术的飞速发展,具身智能不再仅仅是一个技术概念,更像是一把神奇的钥匙。身后的众多行业,无论愿意与否,都像是被卷入一场伟大变革浪潮中的船只,注定要被这股汹涌的力量重塑航向。01为什么是具身智能?为什么在中国?最近,中国具身智能行业的进
    艾迈斯欧司朗 2025-02-28 15:45 160浏览
  •         近日,广电计量在聚焦离子束(FIB)领域编写的专业著作《聚焦离子束:失效分析》正式出版,填补了国内聚焦离子束领域实践性专业书籍的空白,为该领域的技术发展与知识传播提供了重要助力。         随着芯片技术不断发展,芯片的集成度越来越高,结构也日益复杂。这使得传统的失效分析方法面临巨大挑战。FIB技术的出现,为芯片失效分析带来了新的解决方案。它能够在纳米尺度上对芯片进行精确加工和分析。当芯
    广电计量 2025-02-28 09:15 89浏览
  • 应用趋势与客户需求,AI PC的未来展望随着人工智能(AI)技术的日益成熟,AI PC(人工智能个人电脑)逐渐成为消费者和企业工作中的重要工具。这类产品集成了最新的AI处理器,如NPU、CPU和GPU,并具备许多智能化功能,为用户带来更高效且直观的操作体验。AI PC的目标是提升工作和日常生活的效率,通过深度学习与自然语言处理等技术,实现更流畅的多任务处理、实时翻译、语音助手、图像生成等功能,满足现代用户对生产力和娱乐的双重需求。随着各行各业对数字转型需求的增长,AI PC也开始在各个领域中显示
    百佳泰测试实验室 2025-02-27 14:08 238浏览
  • 振动样品磁强计是一种用于测量材料磁性的精密仪器,广泛应用于科研、工业检测等领域。然而,其测量准确度会受到多种因素的影响,下面我们将逐一分析这些因素。一、温度因素温度是影响振动样品磁强计测量准确度的重要因素之一。随着温度的变化,材料的磁性也会发生变化,从而影响测量结果的准确性。因此,在进行磁性测量时,应确保恒温环境,以减少温度波动对测量结果的影响。二、样品制备样品的制备过程同样会影响振动样品磁强计的测量准确度。样品的形状、尺寸和表面处理等因素都会对测量结果产生影响。为了确保测量准确度,应严格按照规
    锦正茂科技 2025-02-28 14:05 117浏览
  • 更多生命体征指标风靡的背后都只有一个原因:更多人将健康排在人生第一顺位!“AGEs,也就是晚期糖基化终末产物,英文名Advanced Glycation End-products,是存在于我们体内的一种代谢产物” 艾迈斯欧司朗亚太区健康监测高级市场经理王亚琴说道,“相信业内的朋友都会有关注,最近该指标的热度很高,它可以用来评估人的生活方式是否健康。”据悉,AGEs是可穿戴健康监测领域的一个“萌新”指标,近来备受关注。如果站在学术角度来理解它,那么AGEs是在非酶促条件下,蛋白质、氨基酸
    艾迈斯欧司朗 2025-02-27 14:50 363浏览
我要评论
0