当前位置: 首页 > news >正文

模型部署:(六)安卓端部署Yolov8分类项目全流程记录

模型部署:(六)安卓端部署Yolov8分类项目全流程记录

在这里插入图片描述

// Tencent is pleased to support the open source community by making ncnn available.
// 说明:这是 Tencent 开源 ncnn 框架的一部分声明,强调版权和许可信息。
// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// https://opensource.org/licenses/BSD-3-Clause
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.#ifndef YOLOV8_H
#define YOLOV8_H
// 防止头文件重复包含(Include Guard),确保编译器只处理一次 YOLOv8_H#include <opencv2/core/core.hpp>
// 包含 OpenCV 核心模块,用于处理 cv::Mat、cv::Point、cv::Rect 等基础类型#include <net.h>
// 包含 ncnn 的网络类 ncnn::Net,YOLOv8 内部用它加载和运行模型// 定义关键点结构体
struct KeyPoint
{cv::Point2f p; // 关键点的二维坐标 (x, y),浮点类型float prob;    // 关键点的置信度
};// 定义检测目标对象结构体
struct Object
{cv::Rect_<float> rect;        // 目标的矩形边界框(普通矩形)cv::RotatedRect rrect;        // 目标的旋转矩形(可旋转检测框)int label;                    // 目标类别索引float prob;                   // 目标置信度int gindex;                   // 全局索引或分组索引(根据业务可能用作 tracking 或类别分组)cv::Mat mask;                 // 目标的掩码(用于分割任务)std::vector<KeyPoint> keypoints; // 目标关键点列表(用于姿态检测)
};// YOLOv8 基类
class YOLOv8
{
public:virtual ~YOLOv8(); // 虚析构函数,确保继承类析构时能正确释放资源// 从文件路径加载模型参数和权重int load(const char* parampath, const char* modelpath, bool use_gpu = false);// 从 Android AAssetManager 资产加载模型(适用于 Android 平台)int load(AAssetManager* mgr, const char* parampath, const char* modelpath, bool use_gpu = false);// 设置检测输入的目标尺寸(通常用于缩放输入图像)void set_det_target_size(int target_size);// 纯虚函数:检测函数,每个子类必须实现virtual int detect(const cv::Mat& rgb, std::vector<Object>& objects) = 0;// 纯虚函数:绘制函数,用于在图像上绘制检测结果,每个子类必须实现virtual int draw(cv::Mat& rgb, const std::vector<Object>& objects) = 0;protected:ncnn::Net yolov8;   // NCNN 网络对象,用于加载和运行 YOLOv8 模型int det_target_size; // 检测输入尺寸
};// YOLOv8 检测子类(普通目标检测)
class YOLOv8_det : public YOLOv8
{
public:virtual int detect(const cv::Mat& rgb, std::vector<Object>& objects);// YOLOv8_det 提供 detect 函数实现
};// YOLOv8 检测 + COCO 绘制风格
class YOLOv8_det_coco : public YOLOv8_det
{
public:virtual int draw(cv::Mat& rgb, const std::vector<Object>& objects);// 实现 draw 函数,绘制 COCO 风格框和标签
};// YOLOv8 检测 + OIV7 绘制风格
class YOLOv8_det_oiv7 : public YOLOv8_det
{
public:virtual int draw(cv::Mat& rgb, const std::vector<Object>& objects);// 实现 draw 函数,绘制 OIV7 风格框和标签
};// YOLOv8 分割子类
class YOLOv8_seg : public YOLOv8
{
public:virtual int detect(const cv::Mat& rgb, std::vector<Object>& objects);virtual int draw(cv::Mat& rgb, const std::vector<Object>& objects);// detect 实现分割预测,draw 绘制掩码等结果
};// YOLOv8 姿态子类
class YOLOv8_pose : public YOLOv8
{
public:virtual int detect(const cv::Mat& rgb, std::vector<Object>& objects);virtual int draw(cv::Mat& rgb, const std::vector<Object>& objects);// detect 实现关键点检测,draw 绘制关键点和骨架
};// YOLOv8 分类子类
class YOLOv8_cls : public YOLOv8
{
public:virtual int detect(const cv::Mat& rgb, std::vector<Object>& objects);virtual int draw(cv::Mat& rgb, const std::vector<Object>& objects);// detect 实现图像分类,draw 绘制分类结果
};// YOLOv8 旋转检测子类
class YOLOv8_obb : public YOLOv8
{
public:virtual int detect(const cv::Mat& rgb, std::vector<Object>& objects);virtual int draw(cv::Mat& rgb, const std::vector<Object>& objects);// detect 实现旋转框检测,draw 绘制旋转框
};#endif // YOLOV8_H
// 结束头文件防重复包含

在这里插入图片描述

// Tencent is pleased to support the open source community by making ncnn available.
// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// https://opensource.org/licenses/BSD-3-Clause
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.#include "yolov8.h" // 包含类声明(YOLOv8)的头文件,通常定义了类成员、ncnn::Net yolov8 等// 析构函数
YOLOv8::~YOLOv8()
{det_target_size = 320; // 在对象销毁时将 det_target_size 设为 320// 注意:在析构函数里设置成员值通常没有实际意义(对象马上就要被销毁)。// 这行更像是应放在构造函数中以初始化默认值。建议改为在构造函数中初始化 det_target_size。
}int YOLOv8::load(const char* parampath, const char* modelpath, bool use_gpu)
{yolov8.clear(); // 清除 ncnn::Net 中已有的参数/模型,保证从空状态重新加载yolov8.opt = ncnn::Option(); // 重置 ncnn 的运行选项为默认值(构造一个新的 Option)#if NCNN_VULKANyolov8.opt.use_vulkan_compute = use_gpu; // 如果编译时开启了 Vulkan 支持,则根据 use_gpu 设置是否使用 Vulkan 计算后端
#endifyolov8.load_param(parampath); // 从文件加载网络结构参数(.param 文件或类似)yolov8.load_model(modelpath); // 从文件加载网络权重(二进制 .bin 文件或类似)return 0; // 返回 0 表示成功(本函数没有做错误检查,若 load_* 失败则不会通过返回值上报)
}int YOLOv8::load(AAssetManager* mgr, const char* parampath, const char* modelpath, bool use_gpu)
{yolov8.clear(); // 同上,清理 Netyolov8.opt = ncnn::Option(); // 重置 Option#if NCNN_VULKANyolov8.opt.use_vulkan_compute = use_gpu; // Vulkan 后端设置(同上)
#endifyolov8.load_param(mgr, parampath); // 从 Android 资产管理器(AAssetManager)中加载 param(适用于 Android 平台)yolov8.load_model(mgr, modelpath); // 从 AAssetManager 加载 model(二进制权重)return 0; // 返回 0 表示成功
}void YOLOv8::set_det_target_size(int target_size)
{det_target_size = target_size; // 设置检测输入的目标尺寸(通常用于内部预处理时的缩放/letterbox)
}

在这里插入图片描述

// Tencent is pleased to support the open source community by making ncnn available.
// // (License header 注释,说明开源许可信息)
// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// https://opensource.org/licenses/BSD-3-Clause
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.// 1. install
//      pip3 install -U ultralytics pnnx ncnn
// 2. export yolov8-cls torchscript
//      yolo export model=yolov8n-cls.pt format=torchscript
// 3. convert torchscript with static shape
//      pnnx yolov8n-cls.torchscript
// 4. now you get ncnn model files
//      yolov8n_cls.ncnn.param
//      yolov8n_cls.ncnn.bin
// (上面为使用流程说明,说明如何从 yolov8-cls 导出并转换为 ncnn 模型文件)#include "yolov8.h" // 引入 yolov8 相关的头文件,包含类声明、Object 定义等#include <opencv2/core/core.hpp> // OpenCV 核心(矩阵、基本类型)
#include <opencv2/imgproc/imgproc.hpp> // OpenCV 图像处理(resize、putText、rectangle 等)#include <float.h> // 提供 FLT_MAX 等浮点相关常量(本文件未必用到)
#include <stdio.h> // C 标准 IO(sprintf 等)
#include <vector> // C++ 向量容器static void get_topk(const ncnn::Mat& cls_scores, int topk, std::vector<Object>& objects)
{// partial sort topk with indexint size = cls_scores.w; // cls_scores 是一个行向量(长度为类别数),w 表示元素个数std::vector<std::pair<float, int> > vec; // 用来存储 (score, index) 对vec.resize(size); // 调整 vec 大小为 sizefor (int i = 0; i < size; i++){vec[i] = std::make_pair(cls_scores[i], i); // 将每个类别的分数和索引放入 vec}std::partial_sort(vec.begin(), vec.begin() + topk, vec.end(),std::greater<std::pair<float, int> >());// 对 vec 的前 topk 元素进行部分排序,使得前 topk 是最大的 topk 个 (按 score 降序)objects.resize(topk); // 调整输出对象数组大小为 topkfor (int i = 0; i < topk; i++){objects[i].label = vec[i].second; // 将索引作为类别标签objects[i].prob = vec[i].first; // 将分数作为概率(注意:这里是原始分数)}
}int YOLOv8_cls::detect(const cv::Mat& rgb, std::vector<Object>& objects)
{const int target_size = 224; // 模型输入的目标尺寸(宽高相同)const int topk = 5; // 期望返回 top5 结果int img_w = rgb.cols; // 输入图像宽 (columns)int img_h = rgb.rows; // 输入图像高 (rows)// letterbox padint w = img_w; // 初始化 w 为原始宽int h = img_h; // 初始化 h 为原始高float scale = 1.f; // 缩放比例初始化为 1if (w > h){scale = (float)target_size / w; // 宽更长时以宽为基准缩放w = target_size; // 缩放后的宽设置为 target_sizeh = h * scale; // 高按同一比例缩放}else{scale = (float)target_size / h; // 高更长或相等时以高为基准缩放h = target_size; // 缩放后的高设置为 target_sizew = w * scale; // 宽按同一比例缩放}ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB, img_w, img_h, w, h);// 把 OpenCV 的 BGR 或 RGB 数据按指定通道格式(这里是 PIXEL_RGB)从内存拷贝并进行 resize// 注意:这里假设 rgb.data 的像素格式为 RGB(变量名为 rgb),若实际为 BGR 需转换或使用 PIXEL_BGR// letterbox pad to target_size rectangleint wpad = target_size - w; // 计算需要在宽方向填充的总像素数int hpad = target_size - h; // 计算需要在高方向填充的总像素数ncnn::Mat in_pad;ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 114.f);// 在图像四周添加边框(top, bottom, left, right),使得图像变为 target_size x target_size// BORDER_CONSTANT 使用常量值填充,常量为 114(常见的图像填充值)const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; // 归一化因子,除以255in_pad.substract_mean_normalize(0, norm_vals);// 对数据进行减均值/归一化,这里 mean 为 0(未减去均值),只做除以 255 的归一化// 注意 ncnn 的接口名是 substract_mean_normalize(拼写如原库),第一个参数传 nullptr(或0)表示不做 mean 减法ncnn::Extractor ex = yolov8.create_extractor(); // 从已加载的 yolov8 网络模型中创建一个提取器(用于前向推理)ex.input("in0", in_pad); // 设置名为 "in0" 的网络输入 blob,输入为处理后的 in_padncnn::Mat out;ex.extract("out0", out); // 提取网络输出名为 "out0" 的 blob 到 out(分类分数向量)// return top-5get_topk(out, topk, objects); // 调用上面的 get_topk 从输出中选取 topk 个概率最大的类别return 0; // 返回 0 表示检测成功(函数约定)
}int YOLOv8_cls::draw(cv::Mat& rgb, const std::vector<Object>& objects)
{static const char* class_names[] = {// 下面是类别名数组,条目非常多(ImageNet 风格类别列表)// 为避免注释冗长,这里不对每一项单独注释:// 该数组的每个字符串对应一个类别标签,索引与模型输出的 label 一一对应。// 在 draw 中,通过 objects[i].label 去查找对应的 class_names[obj.label]。"tench", "goldfish", "great white shark", "tiger shark", "hammerhead", "electric ray", "stingray", "cock","hen", "ostrich", "brambling", "goldfinch", "house finch", "junco", "indigo bunting", "robin", "bulbul","jay", "magpie", "chickadee", "water ouzel", "kite", "bald eagle", "vulture", "great grey owl","European fire salamander", "common newt", "eft", "spotted salamander", "axolotl", "bullfrog", "tree frog","tailed frog", "loggerhead", "leatherback turtle", "mud turtle", "terrapin", "box turtle", "banded gecko","common iguana", "American chameleon", "whiptail", "agama", "frilled lizard", "alligator lizard","Gila monster", "green lizard", "African chameleon", "Komodo dragon", "African crocodile","American alligator", "triceratops", "thunder snake", "ringneck snake", "hognose snake", "green snake","king snake", "garter snake", "water snake", "vine snake", "night snake", "boa constrictor", "rock python","Indian cobra", "green mamba", "sea snake", "horned viper", "diamondback", "sidewinder", "trilobite","harvestman", "scorpion", "black and gold garden spider", "barn spider", "garden spider", "black widow","tarantula", "wolf spider", "tick", "centipede", "black grouse", "ptarmigan", "ruffed grouse","prairie chicken", "peacock", "quail", "partridge", "African grey", "macaw", "sulphur-crested cockatoo","lorikeet", "coucal", "bee eater", "hornbill", "hummingbird", "jacamar", "toucan", "drake","red-breasted merganser", "goose", "black swan", "tusker", "echidna", "platypus", "wallaby", "koala","wombat", "jellyfish", "sea anemone", "brain coral", "flatworm", "nematode", "conch", "snail", "slug","sea slug", "chiton", "chambered nautilus", "Dungeness crab", "rock crab", "fiddler crab", "king crab","American lobster", "spiny lobster", "crayfish", "hermit crab", "isopod", "white stork", "black stork","spoonbill", "flamingo", "little blue heron", "American egret", "bittern", "crane (bird)", "limpkin","European gallinule", "American coot", "bustard", "ruddy turnstone", "red-backed sandpiper", "redshank","dowitcher", "oystercatcher", "pelican", "king penguin", "albatross", "grey whale", "killer whale","dugong", "sea lion", "Chihuahua", "Japanese spaniel", "Maltese dog", "Pekinese", "Shih-Tzu","Blenheim spaniel", "papillon", "toy terrier", "Rhodesian ridgeback", "Afghan hound", "basset", "beagle","bloodhound", "bluetick", "black-and-tan coonhound", "Walker hound", "English foxhound", "redbone","borzoi", "Irish wolfhound", "Italian greyhound", "whippet", "Ibizan hound", "Norwegian elkhound","otterhound", "Saluki", "Scottish deerhound", "Weimaraner", "Staffordshire bullterrier","American Staffordshire terrier", "Bedlington terrier", "Border terrier", "Kerry blue terrier","Irish terrier", "Norfolk terrier", "Norwich terrier", "Yorkshire terrier", "wire-haired fox terrier","Lakeland terrier", "Sealyham terrier", "Airedale", "cairn", "Australian terrier", "Dandie Dinmont","Boston bull", "miniature schnauzer", "giant schnauzer", "standard schnauzer", "Scotch terrier","Tibetan terrier", "silky terrier", "soft-coated wheaten terrier", "West Highland white terrier","Lhasa", "flat-coated retriever", "curly-coated retriever", "golden retriever", "Labrador retriever","Chesapeake Bay retriever", "German short-haired pointer", "vizsla", "English setter", "Irish setter","Gordon setter", "Brittany spaniel", "clumber", "English springer", "Welsh springer spaniel","cocker spaniel", "Sussex spaniel", "Irish water spaniel", "kuvasz", "schipperke", "groenendael","malinois", "briard", "kelpie", "komondor", "Old English sheepdog", "Shetland sheepdog", "collie","Border collie", "Bouvier des Flandres", "Rottweiler", "German shepherd", "Doberman","miniature pinscher", "Greater Swiss Mountain dog", "Bernese mountain dog", "Appenzeller", "EntleBucher","boxer", "bull mastiff", "Tibetan mastiff", "French bulldog", "Great Dane", "Saint Bernard","Eskimo dog", "malamute", "Siberian husky", "dalmatian", "affenpinscher", "basenji", "pug", "Leonberg","Newfoundland", "Great Pyrenees", "Samoyed", "Pomeranian", "chow", "keeshond", "Brabancon griffon","Pembroke", "Cardigan", "toy poodle", "miniature poodle", "standard poodle", "Mexican hairless","timber wolf", "white wolf", "red wolf", "coyote", "dingo", "dhole", "African hunting dog", "hyena","red fox", "kit fox", "Arctic fox", "grey fox", "tabby", "tiger cat", "Persian cat", "Siamese cat","Egyptian cat", "cougar", "lynx", "leopard", "snow leopard", "jaguar", "lion", "tiger", "cheetah","brown bear", "American black bear", "ice bear", "sloth bear", "mongoose", "meerkat", "tiger beetle","ladybug", "ground beetle", "long-horned beetle", "leaf beetle", "dung beetle", "rhinoceros beetle","weevil", "fly", "bee", "ant", "grasshopper", "cricket", "walking stick", "cockroach", "mantis","cicada", "leafhopper", "lacewing", "dragonfly", "damselfly", "admiral", "ringlet", "monarch","cabbage butterfly", "sulphur butterfly", "lycaenid", "starfish", "sea urchin", "sea cucumber","wood rabbit", "hare", "Angora", "hamster", "porcupine", "fox squirrel", "marmot", "beaver","guinea pig", "sorrel", "zebra", "hog", "wild boar", "warthog", "hippopotamus", "ox", "water buffalo","bison", "ram", "bighorn", "ibex", "hartebeest", "impala", "gazelle", "Arabian camel", "llama","weasel", "mink", "polecat", "black-footed ferret", "otter", "skunk", "badger", "armadillo","three-toed sloth", "orangutan", "gorilla", "chimpanzee", "gibbon", "siamang", "guenon", "patas","baboon", "macaque", "langur", "colobus", "proboscis monkey", "marmoset", "capuchin", "howler monkey","titi", "spider monkey", "squirrel monkey", "Madagascar cat", "indri", "Indian elephant","African elephant", "lesser panda", "giant panda", "barracouta", "eel", "coho", "rock beauty","anemone fish", "sturgeon", "gar", "lionfish", "puffer", "abacus", "abaya", "academic gown","accordion", "acoustic guitar", "aircraft carrier", "airliner", "airship", "altar", "ambulance","amphibian", "analog clock", "apiary", "apron", "ashcan", "assault rifle", "backpack", "bakery","balance beam", "balloon", "ballpoint", "Band Aid", "banjo", "bannister", "barbell", "barber chair","barbershop", "barn", "barometer", "barrel", "barrow", "baseball", "basketball", "bassinet", "bassoon","bathing cap", "bath towel", "bathtub", "beach wagon", "beacon", "beaker", "bearskin", "beer bottle","beer glass", "bell cote", "bib", "bicycle-built-for-two", "bikini", "binder", "binoculars","birdhouse", "boathouse", "bobsled", "bolo tie", "bonnet", "bookcase", "bookshop", "bottlecap", "bow","bow tie", "brass", "brassiere", "breakwater", "breastplate", "broom", "bucket", "buckle","bulletproof vest", "bullet train", "butcher shop", "cab", "caldron", "candle", "cannon", "canoe","can opener", "cardigan", "car mirror", "carousel", "carpenter's kit", "carton", "car wheel","cash machine", "cassette", "cassette player", "castle", "catamaran", "CD player", "cello","cellular telephone", "chain", "chainlink fence", "chain mail", "chain saw", "chest", "chiffonier","chime", "china cabinet", "Christmas stocking", "church", "cinema", "cleaver", "cliff dwelling","cloak", "clog", "cocktail shaker", "coffee mug", "coffeepot", "coil", "combination lock","computer keyboard", "confectionery", "container ship", "convertible", "corkscrew", "cornet","cowboy boot", "cowboy hat", "cradle", "crane (machine)", "crash helmet", "crate", "crib","Crock Pot", "croquet ball", "crutch", "cuirass", "dam", "desk", "desktop computer", "dial telephone","diaper", "digital clock", "digital watch", "dining table", "dishrag", "dishwasher", "disk brake","dock", "dogsled", "dome", "doormat", "drilling platform", "drum", "drumstick", "dumbbell","Dutch oven", "electric fan", "electric guitar", "electric locomotive", "entertainment center","envelope", "espresso maker", "face powder", "feather boa", "file", "fireboat", "fire engine","fire screen", "flagpole", "flute", "folding chair", "football helmet", "forklift", "fountain","fountain pen", "four-poster", "freight car", "French horn", "frying pan", "fur coat", "garbage truck","gasmask", "gas pump", "goblet", "go-kart", "golf ball", "golfcart", "gondola", "gong", "gown","grand piano", "greenhouse", "grille", "grocery store", "guillotine", "hair slide", "hair spray","half track", "hammer", "hamper", "hand blower", "hand-held computer", "handkerchief", "hard disc","harmonica", "harp", "harvester", "hatchet", "holster", "home theater", "honeycomb", "hook","hoopskirt", "horizontal bar", "horse cart", "hourglass", "iPod", "iron", "jack-o'-lantern", "jean","jeep", "jersey", "jigsaw puzzle", "jinrikisha", "joystick", "kimono", "knee pad", "knot", "lab coat","ladle", "lampshade", "laptop", "lawn mower", "lens cap", "letter opener", "library", "lifeboat","lighter", "limousine", "liner", "lipstick", "Loafer", "lotion", "loudspeaker", "loupe", "lumbermill","magnetic compass", "mailbag", "mailbox", "maillot (tights)", "maillot (tank suit)", "manhole cover","maraca", "marimba", "mask", "matchstick", "maypole", "maze", "measuring cup", "medicine chest","megalith", "microphone", "microwave", "military uniform", "milk can", "minibus", "miniskirt","minivan", "missile", "mitten", "mixing bowl", "mobile home", "Model T", "modem", "monastery","monitor", "moped", "mortar", "mortarboard", "mosque", "mosquito net", "motor scooter", "mountain bike","mountain tent", "mouse", "mousetrap", "moving van", "muzzle", "nail", "neck brace", "necklace","nipple", "notebook", "obelisk", "oboe", "ocarina", "odometer", "oil filter", "organ", "oscilloscope","overskirt", "oxcart", "oxygen mask", "packet", "paddle", "paddlewheel", "padlock", "paintbrush","pajama", "palace", "panpipe", "paper towel", "parachute", "parallel bars", "park bench","parking meter", "passenger car", "patio", "pay-phone", "pedestal", "pencil box", "pencil sharpener","perfume", "Petri dish", "photocopier", "pick", "pickelhaube", "picket fence", "pickup", "pier","piggy bank", "pill bottle", "pillow", "ping-pong ball", "pinwheel", "pirate", "pitcher", "plane","planetarium", "plastic bag", "plate rack", "plow", "plunger", "Polaroid camera", "pole","police van", "poncho", "pool table", "pop bottle", "pot", "potter's wheel", "power drill","prayer rug", "printer", "prison", "projectile", "projector", "puck", "punching bag", "purse","quill", "quilt", "racer", "racket", "radiator", "radio", "radio telescope", "rain barrel","recreational vehicle", "reel", "reflex camera", "refrigerator", "remote control", "restaurant","revolver", "rifle", "rocking chair", "rotisserie", "rubber eraser", "rugby ball", "rule","running shoe", "safe", "safety pin", "saltshaker", "sandal", "sarong", "sax", "scabbard", "scale","school bus", "schooner", "scoreboard", "screen", "screw", "screwdriver", "seat belt", "sewing machine","shield", "shoe shop", "shoji", "shopping basket", "shopping cart", "shovel", "shower cap","shower curtain", "ski", "ski mask", "sleeping bag", "slide rule", "sliding door", "slot", "snorkel","snowmobile", "snowplow", "soap dispenser", "soccer ball", "sock", "solar dish", "sombrero","soup bowl", "space bar", "space heater", "space shuttle", "spatula", "speedboat", "spider web","spindle", "sports car", "spotlight", "stage", "steam locomotive", "steel arch bridge", "steel drum","stethoscope", "stole", "stone wall", "stopwatch", "stove", "strainer", "streetcar", "stretcher","studio couch", "stupa", "submarine", "suit", "sundial", "sunglass", "sunglasses", "sunscreen","suspension bridge", "swab", "sweatshirt", "swimming trunks", "swing", "switch", "syringe","table lamp", "tank", "tape player", "teapot", "teddy", "television", "tennis ball", "thatch","theater curtain", "thimble", "thresher", "throne", "tile roof", "toaster", "tobacco shop","toilet seat", "torch", "totem pole", "tow truck", "toyshop", "tractor", "trailer truck", "tray","trench coat", "tricycle", "trimaran", "tripod", "triumphal arch", "trolleybus", "trombone", "tub","turnstile", "typewriter keyboard", "umbrella", "unicycle", "upright", "vacuum", "vase", "vault","velvet", "vending machine", "vestment", "viaduct", "violin", "volleyball", "waffle iron", "wall clock","wallet", "wardrobe", "warplane", "washbasin", "washer", "water bottle", "water jug", "water tower","whiskey jug", "whistle", "wig", "window screen", "window shade", "Windsor tie", "wine bottle", "wing","wok", "wooden spoon", "wool", "worm fence", "wreck", "yawl", "yurt", "web site", "comic book","crossword puzzle", "street sign", "traffic light", "book jacket", "menu", "plate", "guacamole","consomme", "hot pot", "trifle", "ice cream", "ice lolly", "French loaf", "bagel", "pretzel","cheeseburger", "hotdog", "mashed potato", "head cabbage", "broccoli", "cauliflower", "zucchini","spaghetti squash", "acorn squash", "butternut squash", "cucumber", "artichoke", "bell pepper","cardoon", "mushroom", "Granny Smith", "strawberry", "orange", "lemon", "fig", "pineapple", "banana","jackfruit", "custard apple", "pomegranate", "hay", "carbonara", "chocolate sauce", "dough","meat loaf", "pizza", "potpie", "burrito", "red wine", "espresso", "cup", "eggnog", "alp", "bubble","cliff", "coral reef", "geyser", "lakeside", "promontory", "sandbar", "seashore", "valley", "volcano","ballplayer", "groom", "scuba diver", "rapeseed", "daisy", "yellow lady's slipper", "corn", "acorn","hip", "buckeye", "coral fungus", "agaric", "gyromitra", "stinkhorn", "earthstar", "hen-of-the-woods","bolete", "ear", "toilet tissue"}; // class_names 数组结束int y_offset = 0; // 文本绘制的竖直偏移,用于逐行显示多个标签for (size_t i = 0; i < objects.size(); i++){const Object& obj = objects[i]; // 获取第 i 个检测对象(只包含 label 与 prob)// fprintf(stderr, "%d = %.5f\n", obj.label, obj.prob); // 可选的调试输出(被注释掉)char text[256];sprintf(text, "%4.1f%% %s", obj.prob * 100, class_names[obj.label]);// 将概率和类别名格式化成文本,例如 "99.9% Labrador retriever"// 注意:obj.prob 通常是 [0,1] 区间的分数,这里乘以 100 并保留 1 位小数int baseLine = 0;cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);// 计算文本所占的像素尺寸,用于绘制背景矩形// 参数依次为 (文本, 字体, 字体缩放, 字体粗细, &baseline)int x = 0; // 文本绘制的 x 坐标(左上角)int y = y_offset; // 文本绘制的 y 坐标(左上角),使用 y_offset 来堆叠多行文本cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),cv::Scalar(255, 255, 255), -1);// 绘制一个白色填充的矩形作为文本背景,参数 -1 表示填充cv::putText(rgb, text, cv::Point(x, y + label_size.height),cv::FONT_HERSHEY_SIMPLEX, 0.3, cv::Scalar(0, 0, 0));// 在背景矩形上绘制黑色文本,注意 y + label_size.height 使得文本基线对齐到矩形内部y_offset += label_size.height; // 更新 y_offset,为下一行文本腾出垂直空间}return 0; // 返回 0 表示绘制完成
}
http://www.dtcms.com/a/389433.html

相关文章:

  • android 查看apk签名信息
  • SQL提取国家名称与延伸词技巧
  • 通过 商业智能 BI 数据分析提升客流量和销售额
  • PostgreSQL 与 MySQL 谁的地位更高?——全方位对比分析
  • rust编写web服务08-配置管理与日志
  • 浏览器事件机制里,事件冒泡和事件捕获的具体区别是什么?在React的合成事件体系下有什么不同的?
  • 企业级实战:构建基于Qt、C++与YOLOv8的模块化工业视觉检测系统(基于QML)
  • 【Java】Ubuntu上发布Springboot 网站
  • 【入门级-算法-3、基础算法:贪心法】
  • Linux 网络
  • 【LVS入门宝典】探秘LVS透明性:客户端如何“看不见”后端服务器的魔法
  • 23届考研-C++面经(OD)
  • 运维安全06,服务安全
  • C++篇(9)list的模拟实现
  • Bugku-宽带信息泄露
  • LeetCode 845.数组中的最长山脉
  • 分布式存储与NFS:现代架构选型指南
  • SpringBoot三级缓存如何解决循环依赖的问题
  • 火山引擎 veCLI 发布,开启智能开发新模式
  • UE学习记录11----地形数据获取等高线
  • 【C++】STL--priority_queue(优先级队列)使用及其模拟实现、容器适配器和deque(双端队列)了解
  • 数学差能学人工智能吗?
  • Verilog语法学习EP10:串口接收模块
  • 使用obs同步录制窗口的高质量游戏模式视频
  • Qt语言家的简单使用记录
  • Taro + vue3项目,如何生成安卓 apk 安装包
  • Hive HQL命令
  • 智慧医疗新纪元:快瞳科技如何用OCR技术重塑医疗单据处理体验
  • 4.1软件工程管理-CMM2软件项目规划-思考题
  • 知识图谱对自然语言处理深层语义分析的影响与启示:2025年研究综述