【Yolov8 Opencv C++系列保姆教程】Yolov8 opencv c++ 版本保姆教程,Yolov8训练自己的数据集,实现红绿灯识别及红绿灯故障检测 ,红绿灯故障识别。

目录

一、Yolov8简介

1、yolov8 源码地址:

2、官方文档:

3、预训练模型百度网盘地址:

二、模型训练

1、标定红绿灯数据:

2、训练环境:

3、数据转化:

4、构造训练数据:

5、训练样本:

三、验证模型:

1、图像测试:

2、视频测试:

四、导出ONNX

五、Opencv实现Yolov8 C++ 识别

1、开发环境:

2、main函数代码:

3、yolov8 头文件inference.h代码:

4、yolov8 cpp文件inference.cpp代码:


一、Yolov8简介

1、yolov8 源码地址:

工程链接:https://github.com/ultralytics/ultralytics

2、官方文档:

CLI - Ultralytics YOLOv8 Docs

3、预训练模型百度网盘地址:

训练时需要用到,下载的网址较慢:

如果模型下载不了,加QQ:187100248.

链接: https://pan.baidu.com/s/1YfMxRPGk8LF75a4cbgYxGg 提取码: rd7b

二、模型训练

1、标定红绿灯数据:

         类别为23类,分别为:

红绿灯类别
red_lightgreen_lightyellow_lightoff_lightpart_ry_lightpart_rg_light
part_yg_lightryg_lightcountdown_off_lightcountdown_on_lightshade_lightzero
onetwothreefourfivesix
seveneightninebrokeNumberbrokenLight

        标注工具地址:AI标注工具Labelme和LabelImage Labelme和LabelImage集成工具_labelimage与labelme-CSDN博客

标注后图像格式

2、训练环境:

1)、Ubuntu18.04;

2)、Cuda11.7 + CUDNN8.0.6;

3)、opencv4.5.5;

4)、PyTorch1.8.1-GPU;

5)、python3.9

3、数据转化:

 1)、需要把上面标定的数据集中的.xml文件转换为.txt,转换代码为:

import os
import shutil
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element, SubElement
from PIL import Image
import cv2

classes = ['red_light', 'green_light', 'yellow_light', 'off_light', 'part_ry_light', 'part_rg_light', 'part_yg_light', 'ryg_light',
           'countdown_off_light', 'countdown_on_light','shade_light','zero','one','two','three','four','five','six','seven',
           'eight','nine','brokeNumber','brokenLight']

class Xml_make(object):
    def __init__(self):
        super().__init__()

    def __indent(self, elem, level=0):
        i = "\n" + level * "\t"
        if len(elem):
            if not elem.text or not elem.text.strip():
                elem.text = i + "\t"
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
            for elem in elem:
                self.__indent(elem, level + 1)
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
        else:
            if level and (not elem.tail or not elem.tail.strip()):
                elem.tail = i

    def _imageinfo(self, list_top):
        annotation_root = ET.Element('annotation')
        annotation_root.set('verified', 'no')
        tree = ET.ElementTree(annotation_root)
        '''
        0:xml_savepath 1:folder,2:filename,3:path
        4:checked,5:width,6:height,7:depth
        '''
        folder_element = ET.Element('folder')
        folder_element.text = list_top[1]
        annotation_root.append(folder_element)

        filename_element = ET.Element('filename')
        filename_element.text = list_top[2]
        annotation_root.append(filename_element)

        path_element = ET.Element('path')
        path_element.text = list_top[3]
        annotation_root.append(path_element)

        # checked_element = ET.Element('checked')
        # checked_element.text = list_top[4]
        # annotation_root.append(checked_element)

        source_element = ET.Element('source')
        database_element = SubElement(source_element, 'database')
        database_element.text = 'Unknown'
        annotation_root.append(source_element)

        size_element = ET.Element('size')
        width_element = SubElement(size_element, 'width')
        width_element.text = str(list_top[5])
        height_element = SubElement(size_element, 'height')
        height_element.text = str(list_top[6])
        depth_element = SubElement(size_element, 'depth')
        depth_element.text = str(list_top[7])
        annotation_root.append(size_element)

        segmented_person_element = ET.Element('segmented')
        segmented_person_element.text = '0'
        annotation_root.append(segmented_person_element)

        return tree, annotation_root

    def _bndbox(self, annotation_root, list_bndbox):
        for i in range(0, len(list_bndbox), 9):
            object_element = ET.Element('object')
            name_element = SubElement(object_element, 'name')
            name_element.text = list_bndbox[i]

            # flag_element = SubElement(object_element, 'flag')
            # flag_element.text = list_bndbox[i + 1]

            pose_element = SubElement(object_element, 'pose')
            pose_element.text = list_bndbox[i + 2]

            truncated_element = SubElement(object_element, 'truncated')
            truncated_element.text = list_bndbox[i + 3]

            difficult_element = SubElement(object_element, 'difficult')
            difficult_element.text = list_bndbox[i + 4]

            bndbox_element = SubElement(object_element, 'bndbox')
            xmin_element = SubElement(bndbox_element, 'xmin')
            xmin_element.text = str(list_bndbox[i + 5])

            ymin_element = SubElement(bndbox_element, 'ymin')
            ymin_element.text = str(list_bndbox[i + 6])

            xmax_element = SubElement(bndbox_element, 'xmax')
            xmax_element.text = str(list_bndbox[i + 7])

            ymax_element = SubElement(bndbox_element, 'ymax')
            ymax_element.text = str(list_bndbox[i + 8])

            annotation_root.append(object_element)

        return annotation_root

    def txt_to_xml(self, list_top, list_bndbox):
        tree, annotation_root = self._imageinfo(list_top)
        annotation_root = self._bndbox(annotation_root, list_bndbox)
        self.__indent(annotation_root)
        tree.write(list_top[0], encoding='utf-8', xml_declaration=True)

def txt_2_xml(source_path, xml_save_dir, jpg_save_dir,txt_dir):

    COUNT = 0
    for folder_path_tuple, folder_name_list, file_name_list in os.walk(source_path):
        for file_name in file_name_list:
            file_suffix = os.path.splitext(file_name)[-1]
            if file_suffix != '.jpg':
                continue
            list_top = []
            list_bndbox = []
            path = os.path.join(folder_path_tuple, file_name)
            xml_save_path = os.path.join(xml_save_dir, file_name.replace(file_suffix, '.xml'))
            txt_path = os.path.join(txt_dir, file_name.replace(file_suffix, '.txt'))
            filename = file_name#os.path.splitext(file_name)[0]
            checked = 'NO'
            #print(file_name)
            im = Image.open(path)
            im_w = im.size[0]
            im_h = im.size[1]

            shutil.copy(path, jpg_save_dir)


            if im_w*im_h > 34434015:
                print(file_name)
            if im_w < 100:
                print(file_name)

            width = str(im_w)
            height = str(im_h)
            depth = '3'
            flag = 'rectangle'
            pose = 'Unspecified'
            truncated = '0'
            difficult = '0'
            list_top.extend([xml_save_path, folder_path_tuple, filename, path, checked, width, height, depth])
            for line in open(txt_path, 'r'):
                line = line.strip()
                info = line.split(' ')
                name = classes[int(info[0])]
                x_cen = float(info[1]) * im_w
                y_cen = float(info[2]) * im_h
                w = float(info[3]) * im_w
                h = float(info[4]) * im_h
                xmin = int(x_cen - w / 2) - 1
                ymin = int(y_cen - h / 2) - 1
                xmax = int(x_cen + w / 2) + 3
                ymax = int(y_cen + h / 2) + 3

                if xmin < 0:
                    xmin = 0
                if ymin < 0:
                    ymin = 0

                if xmax > im_w - 1:
                    xmax = im_w - 1
                if ymax > im_h - 1:
                    ymax = im_h - 1

                if w > 5 and h > 5:
                  list_bndbox.extend([name, flag, pose, truncated, difficult,str(xmin), str(ymin), str(xmax), str(ymax)])

                if xmin < 0 or xmax > im_w - 1 or ymin < 0 or ymax > im_h - 1:
                    print(xml_save_path)

            Xml_make().txt_to_xml(list_top, list_bndbox)
            COUNT += 1
            #print(COUNT, xml_save_path)

if __name__ == "__main__":

    out_xml_path = "/home/TL_TrainData/"  # .xml输出文件存放地址
    out_jpg_path = "/home/TL_TrainData/"  # .jpg输出文件存放地址
    txt_path = "/home/Data/TrafficLight/trainData"  # yolov3标注.txt和图片文件夹
    images_path = "/home/TrafficLight/trainData"  # image文件存放地址
    txt_2_xml(images_path, out_xml_path, out_jpg_path, txt_path)

4、构造训练数据:

2)、训练样本数据构造,需要把分成images和labels,images下面放入图片,labels下面放入.txt文件:

分成images和labels
分成images和labels
images
labels

5、训练样本:

 1)、首先安装训练包:

pip install ultralytics

2)、修改训练数据参数coco128_light.yaml文件,这个是自己修改的。

# Ultralytics YOLO 🚀, AGPL-3.0 license
# COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics
# Example usage: yolo train data=coco128.yaml
# parent
# ├── ultralytics
# └── datasets
#     └── coco128  ← downloads here (7 MB)


# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: /home/Data/TrafficLight/datasets  # dataset root dir
train: images  # train images (relative to 'path') 128 images
val: images  # val images (relative to 'path') 128 images
test:  # test images (optional)

# Parameters
nc: 23  # number of classes

# Classes
names:
  0: red_light
  1: green_light
  2: yellow_light
  3: off_light
  4: part_ry_light
  5: part_rg_light
  6: part_yg_light
  7: ryg_light
  8: countdown_off_light
  9: countdown_on_light
  10: shade_light
  11: zero
  12: one
  13: two
  14: three
  15: four
  16: five
  17: six
  18: seven
  19: eight
  20: nine
  21: brokeNumber
  22: brokenLight

# Download script/URL (optional)
#download: https://ultralytics.com/assets/coco128.zip

3)、执行 train_yolov8x_light.sh,内容为:

yolo detect train data=coco128_light.yaml model=./runs/last.pt epochs=100 imgsz=640 workers=16 batch=32

        开始启动训练:

        

模型训练启动

三、验证模型:

1、图像测试:

from ultralytics import YOLO

# Load a model
#model = YOLO('yolov8n.pt')  # load an official model
model = YOLO('best.pt')  # load a custom model

# Predict with the model
results = model('bus.jpg')  # predict on an image

# View results
for r in results:
    print(r.boxes)  # print the Boxes object containing the detection bounding boxes

2、视频测试:

import cv2
from ultralytics import YOLO

# Load the YOLOv8 model
model = YOLO('best.pt')

# Open the video file
video_path = "test_car_person_1080P.mp4"
cap = cv2.VideoCapture(video_path)

# Loop through the video frames
while cap.isOpened():
    # Read a frame from the video
    success, frame = cap.read()

    if success:
        # Run YOLOv8 inference on the frame
        results = model(frame)

        # Visualize the results on the frame
        annotated_frame = results[0].plot()

        # Display the annotated frame
        cv2.imshow("YOLOv8 Inference", annotated_frame)
        cv2.waitKey(10)

四、导出ONNX

1、训练输出,经过上面的训练后,得到训练生成文件,weights下生成了best.pt和last.pt:

训练数据生成文件

2、等训练完毕后,利用best.pt生成best.onnx,执行命令如下:

yolo export model=best.pt imgsz=640 format=onnx opset=12

五、Opencv实现Yolov8 C++ 识别

1、开发环境:

1)、win7/win10;

2)、vs2019;

3)、opencv4.7.0;

2、main函数代码:

#include <iostream>
#include <vector>
#include "opencv2/opencv.hpp"
#include "inference.h"
#include <io.h>
#include <thread>
#define socklen_t int
#pragma comment (lib, "ws2_32.lib")

using namespace std;
using namespace cv;

int getFiles(std::string path, std::vector<std::string>& files, std::vector<std::string>& names)
{
    int i = 0;
    intptr_t hFile = 0;
    struct _finddata_t c_file;
    std::string imageFile = path + "*.*";

    if ((hFile = _findfirst(imageFile.c_str(), &c_file)) == -1L)
    {
        _findclose(hFile);
        return -1;
    }
    else
    {
        while (true)
        {
            std::string strname(c_file.name);
            if (std::string::npos != strname.find(".jpg") || std::string::npos != strname.find(".png") || std::string::npos != strname.find(".bmp"))
            {
                std::string fullName = path + c_file.name;

                files.push_back(fullName);

                std::string cutname = strname.substr(0, strname.rfind("."));
                names.push_back(cutname);
            }

            if (_findnext(hFile, &c_file) != 0)
            {
                _findclose(hFile);
                break;
            }
        }
    }

    return 0;
}

int main()
{
    std::string projectBasePath = "./"; // Set your ultralytics base path

    bool runOnGPU = true;

    //
    // Pass in either:
    //
    // "yolov8s.onnx" or "yolov5s.onnx"
    //
    // To run Inference with yolov8/yolov5 (ONNX)
    //

    // Note that in this example the classes are hard-coded and 'classes.txt' is a place holder.
    Inference inf(projectBasePath + "/best.onnx", cv::Size(640, 640), "classes.txt", runOnGPU);

    std::vector<std::string> files;
    std::vector<std::string> names;
    getFiles("./test/", files, names);

    //std::vector<std::string> imageNames;
    //imageNames.push_back(projectBasePath + "/test/20221104_8336.jpg");
    //imageNames.push_back(projectBasePath + "/test/20221104_8339.jpg");

    for (int i = 0; i < files.size(); ++i)
    {
        cv::Mat frame = cv::imread(files[i]);

        // Inference starts here...
        clock_t start, end;
        float time;
        start = clock();
        std::vector<Detection> output = inf.runInference(frame);
        end = clock();
        time = (float)(end - start);//CLOCKS_PER_SEC; 
        printf("timeCount = %f\n", time);

        int detections = output.size();
        std::cout << "Number of detections:" << detections << std::endl;

        for (int i = 0; i < detections; ++i)
        {
            Detection detection = output[i];

            cv::Rect box = detection.box;
            cv::Scalar color = detection.color;

            // Detection box
            cv::rectangle(frame, box, color, 2);

            // Detection box text
            std::string classString = detection.className + ' ' + std::to_string(detection.confidence).substr(0, 4);
            cv::Size textSize = cv::getTextSize(classString, cv::FONT_HERSHEY_DUPLEX, 1, 2, 0);
            cv::Rect textBox(box.x, box.y - 40, textSize.width + 10, textSize.height + 20);

            cv::rectangle(frame, textBox, color, cv::FILLED);
            cv::putText(frame, classString, cv::Point(box.x + 5, box.y - 10), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 0, 0), 2, 0);
        }
        // Inference ends here...

        // This is only for preview purposes
        float scale = 0.8;
        cv::resize(frame, frame, cv::Size(frame.cols * scale, frame.rows * scale));
        cv::imshow("Inference", frame);

        cv::waitKey(10);
    }
}

3、yolov8 头文件inference.h代码:

#ifndef INFERENCE_H
#define INFERENCE_H

// Cpp native
#include <fstream>
#include <vector>
#include <string>
#include <random>

// OpenCV / DNN / Inference
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>

struct Detection
{
    int class_id{0};
    std::string className{};
    float confidence{0.0};
    cv::Scalar color{};
    cv::Rect box{};
};

class Inference
{
public:
    Inference(const std::string &onnxModelPath, const cv::Size &modelInputShape = {640, 640}, const std::string &classesTxtFile = "", const bool &runWithCuda = true);
    std::vector<Detection> runInference(const cv::Mat &input);

private:
    void loadClassesFromFile();
    void loadOnnxNetwork();
    cv::Mat formatToSquare(const cv::Mat &source);

    std::string modelPath{};
    std::string classesPath{};
    bool cudaEnabled{};

    std::vector<std::string> classes{ "red_light", "green_light", "yellow_light", "off_light", "part_ry_light", "part_rg_light", "part_yg_light", "ryg_light","countdown_off_light", "countdown_on_light","shade_light","zero","one","two","three","four","five","six","seven","eight","nine","brokeNumber","brokenLight" };

    cv::Size2f modelShape{};

    float modelConfidenceThreshold {0.25};
    float modelScoreThreshold      {0.45};
    float modelNMSThreshold        {0.50};

    bool letterBoxForSquare = true;

    cv::dnn::Net net;
};

#endif // INFERENCE_H

4、yolov8 cpp文件inference.cpp代码:

#include "inference.h"

Inference::Inference(const std::string &onnxModelPath, const cv::Size &modelInputShape, const std::string &classesTxtFile, const bool &runWithCuda)
{
    modelPath = onnxModelPath;
    modelShape = modelInputShape;
    classesPath = classesTxtFile;
    cudaEnabled = runWithCuda;

    loadOnnxNetwork();
    // loadClassesFromFile(); The classes are hard-coded for this example
}

std::vector<Detection> Inference::runInference(const cv::Mat &input)
{
    cv::Mat modelInput = input;
    if (letterBoxForSquare && modelShape.width == modelShape.height)
        modelInput = formatToSquare(modelInput);

    cv::Mat blob;
    cv::dnn::blobFromImage(modelInput, blob, 1.0/255.0, modelShape, cv::Scalar(), true, false);
    net.setInput(blob);

    std::vector<cv::Mat> outputs;
    net.forward(outputs, net.getUnconnectedOutLayersNames());

    int rows = outputs[0].size[1];
    int dimensions = outputs[0].size[2];

    bool yolov8 = false;
    // yolov5 has an output of shape (batchSize, 25200, 85) (Num classes + box[x,y,w,h] + confidence[c])
    // yolov8 has an output of shape (batchSize, 84,  8400) (Num classes + box[x,y,w,h])
    if (dimensions > rows) // Check if the shape[2] is more than shape[1] (yolov8)
    {
        yolov8 = true;
        rows = outputs[0].size[2];
        dimensions = outputs[0].size[1];

        outputs[0] = outputs[0].reshape(1, dimensions);
        cv::transpose(outputs[0], outputs[0]);
    }
    float *data = (float *)outputs[0].data;

    float x_factor = modelInput.cols / modelShape.width;
    float y_factor = modelInput.rows / modelShape.height;

    std::vector<int> class_ids;
    std::vector<float> confidences;
    std::vector<cv::Rect> boxes;

    for (int i = 0; i < rows; ++i)
    {
        if (yolov8)
        {
            float *classes_scores = data+4;

            cv::Mat scores(1, classes.size(), CV_32FC1, classes_scores);
            cv::Point class_id;
            double maxClassScore;

            minMaxLoc(scores, 0, &maxClassScore, 0, &class_id);

            if (maxClassScore > modelScoreThreshold)
            {
                confidences.push_back(maxClassScore);
                class_ids.push_back(class_id.x);

                float x = data[0];
                float y = data[1];
                float w = data[2];
                float h = data[3];

                int left = int((x - 0.5 * w) * x_factor);
                int top = int((y - 0.5 * h) * y_factor);

                int width = int(w * x_factor);
                int height = int(h * y_factor);

                boxes.push_back(cv::Rect(left, top, width, height));
            }
        }
        else // yolov5
        {
            float confidence = data[4];

            if (confidence >= modelConfidenceThreshold)
            {
                float *classes_scores = data+5;

                cv::Mat scores(1, classes.size(), CV_32FC1, classes_scores);
                cv::Point class_id;
                double max_class_score;

                minMaxLoc(scores, 0, &max_class_score, 0, &class_id);

                if (max_class_score > modelScoreThreshold)
                {
                    confidences.push_back(confidence);
                    class_ids.push_back(class_id.x);

                    float x = data[0];
                    float y = data[1];
                    float w = data[2];
                    float h = data[3];

                    int left = int((x - 0.5 * w) * x_factor);
                    int top = int((y - 0.5 * h) * y_factor);

                    int width = int(w * x_factor);
                    int height = int(h * y_factor);

                    boxes.push_back(cv::Rect(left, top, width, height));
                }
            }
        }

        data += dimensions;
    }

    std::vector<int> nms_result;
    cv::dnn::NMSBoxes(boxes, confidences, modelScoreThreshold, modelNMSThreshold, nms_result);

    std::vector<Detection> detections{};
    for (unsigned long i = 0; i < nms_result.size(); ++i)
    {
        int idx = nms_result[i];

        Detection result;
        result.class_id = class_ids[idx];
        result.confidence = confidences[idx];

        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<int> dis(100, 255);
        result.color = cv::Scalar(dis(gen),
                                  dis(gen),
                                  dis(gen));

        result.className = classes[result.class_id];
        result.box = boxes[idx];

        detections.push_back(result);
    }

    return detections;
}

void Inference::loadClassesFromFile()
{
    std::ifstream inputFile(classesPath);
    if (inputFile.is_open())
    {
        std::string classLine;
        while (std::getline(inputFile, classLine))
            classes.push_back(classLine);
        inputFile.close();
    }
}

void Inference::loadOnnxNetwork()
{
    net = cv::dnn::readNetFromONNX(modelPath);
    if (cudaEnabled)
    {
        std::cout << "\nRunning on CUDA" << std::endl;
        net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
        net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
    }
    else
    {
        std::cout << "\nRunning on CPU" << std::endl;
        net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
        net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
    }
}

cv::Mat Inference::formatToSquare(const cv::Mat &source)
{
    int col = source.cols;
    int row = source.rows;
    int _max = MAX(col, row);
    cv::Mat result = cv::Mat::zeros(_max, _max, CV_8UC3);
    source.copyTo(result(cv::Rect(0, 0, col, row)));
    return result;
}

4、效果图:

vs2019工程运行结果
红绿灯识别结果
  • 29
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
【项目介绍】 基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip 基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip 基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip基于OpenCV部署yolov8的人脸检测+关键点检测源码(python和c++版本,可换成车牌检测4个角点).zip 【备注】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载食用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈!
### 回答1: 要使用OpenCV训练YOLOv8模型,需要按照以下步骤进行操作: 1. 数据集准备: 首先,需要准备自己的数据集数据集应包含图像和相应的标签文件,标签文件中包含每个图像中目标物体的类别和坐标信息。确保数据集中的目标物体类别与预定义的YOLOv8模型类别一致。 2. 标注图像: 使用标注工具,如LabelImg,对数据集中的图像进行标注。标注包括在图像中框出目标物体,并为每个框提供类别标签和坐标信息。标注完成后,会产生相应的标签文件。 3. 数据集划分: 将数据集划分为训练集和验证集。通常,将大部分数据用于训练,少部分用于验证。划分的比例可以根据需求进行调整。 4. 数据预处理: 对图像进行预处理,以满足YOLOv8模型的输入要求。例如,可以调整图像大小、归一化图像像素值等。 5. 配置文件: 创建YOLOv8的配置文件,其中包含模型的超参数设置、数据集路径、类别数目等信息。可参考Darknet框架提供的示例配置文件进行修改。 6. 网络模型训练: 使用OpenCV加载YOLOv8模型,并对其进行训练。在训练过程中,通过调整超参数、学习率等来优化模型的性能。训练过程中,模型会根据训练集的图像和标签进行梯度下降更新权重。 7. 模型评估和调优: 使用验证集对训练好的模型进行评估,通过计算精度、召回率等指标来评估模型的性能。若模型效果不佳,可尝试调整训练策略、数据增强等方法来改进模型。 8. 模型应用: 训练完成后,可以使用OpenCV中的YOLOv8模型进行目标检测。加载模型并输入待检测的图像,模型会输出检测到的目标物体的类别和坐标信息。 总结: 使用OpenCV训练YOLOv8模型的过程包括数据集准备、标注图像、数据预处理、配置文件创建、网络模型训练、模型评估和调优等步骤。这些步骤能够帮助我们基于自己的数据集训练出一个适用于目标检测的YOLOv8模型。 ### 回答2: YOLOv8是一种先进的目标检测算法,它可以通过训练自己的数据集实现目标检测任务。在使用YOLOv8之前,我们需要准备自己的数据集并进行标注。 准备训练数据集时,需要收集包含目标的图像,并对每个目标进行标注。标注的方法一般有两种:边界框标注和像素级标注。对于YOLOv8算法,我们一般使用边界框标注,即在图像中标注出目标的边界框。 在数据集准备完毕后,我们需要使用OpenCV库进行数据处理。首先,我们需要读取每张图像,并对其进行预处理,例如调整大小、归一化等。接下来,我们需要将标注的目标边界框转换为YOLOv8要求的格式。YOLOv8的目标标注格式是每个目标的类别编号和边界框的四个坐标值。 在进行训练之前,我们还需要准备一个包含所有类别名称的文件,该文件将用于指导YOLOv8识别和分类目标。 训练YOLOv8的过程中,我们需要定义网络结构,并设置一些超参数,如学习率、批次大小和训练轮数等。然后,我们可以使用准备好的数据集对网络进行训练训练过程中,YOLOv8会不断调整模型参数,以提高目标检测的准确率。 在训练完成后,我们可以使用自己的数据集来测试训练好的YOLOv8模型。通过输入测试图像,YOLOv8将输出检测到的目标类别和位置信息。 总之,YOLOv8是一种强大的目标检测算法,通过使用OpenCV库和自己的数据集,我们可以训练出适用于特定任务的自定义目标检测模型。 ### 回答3: YOLOv8是一种目标检测算法,可以用于训练自己的数据集OpenCV是一个开源的计算机视觉库,它提供了一系列图像处理和计算机视觉算法的函数和工具。 要用YOLOv8训练自己的数据集,首先需要准备好以下几个步骤: 1. 数据集准备:收集图像数据并对其进行标注,将目标物体的边界框和类别信息标记出来。可以使用OpenCV的绘图功能来手动标注数据集,也可以使用一些标注工具来自动标注。 2. 数据集划分:将数据集划分为训练集、验证集和测试集。通常会将大部分样本用于训练,一小部分用于验证和测试。 3. 配置文件:YOLOv8通过配置文件定义了一些重要的参数,如网络结构、训练参数、数据集路径等。可以使用OpenCV读取和修改这些配置文件。 4. 模型训练:使用准备好的数据集和配置文件,将YOLOv8模型进行训练。可以使用OpenCV的图像读取和预处理功能来加载数据集,然后使用训练算法进行迭代优化,直到模型收敛或达到预定的训练轮次。 5. 模型评估:训练完成后,可以使用测试集对训练好的模型进行评估,计算准确率、召回率等指标,来判断模型的性能。 最后,要注意的是,这只是一个概要的流程。实际上,使用YOLOv8训练自己的数据集需要解决很多实际问题,如数据预处理、模型调参、训练策略等。使用OpenCV可以提供一些便利的功能和接口,但需要更深入的学习和实践才能掌握这些技术。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值