能不能给我一个opencv的c++的yolo代码
时间: 2024-03-14 14:45:38 浏览: 161
C++ opencv部署yolov8旋转框目标检测源码
5星 · 资源好评率100%
以下是一个使用OpenCV C++封装的YOLOv4检测器的代码示例:
```cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <opencv2/opencv.hpp>
class YOLO {
public:
YOLO(const std::string& cfg_path, const std::string& weights_path, float confidence_threshold = 0.5, float nms_threshold = 0.5, int input_width = 416, int input_height = 416, const std::vector<std::string>& class_names = {})
: confidence_threshold_(confidence_threshold), nms_threshold_(nms_threshold), input_width_(input_width), input_height_(input_height), class_names_(class_names) {
net_ = cv::dnn::readNetFromDarknet(cfg_path, weights_path);
net_.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
net_.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
output_names_ = net_.getUnconnectedOutLayersNames();
}
std::vector<cv::Rect> detect(const cv::Mat& image) {
cv::Mat blob = cv::dnn::blobFromImage(image, 1 / 255.0, cv::Size(input_width_, input_height_), cv::Scalar(0, 0, 0), true, false);
net_.setInput(blob);
std::vector<cv::Mat> outputs;
net_.forward(outputs, output_names_);
std::vector<cv::Rect> boxes;
std::vector<int> class_ids;
std::vector<float> confidences;
for (const auto& output : outputs) {
cv::Mat detection = output.reshape(1, output.total() / 7);
for (int i = 0; i < detection.rows; ++i) {
cv::Mat row = detection.row(i);
cv::Mat scores = row.colRange(5, detection.cols);
cv::Point class_id;
double confidence;
cv::minMaxLoc(scores, nullptr, &confidence, nullptr, &class_id);
if (confidence > confidence_threshold_) {
int x_center = static_cast<int>(row.at<float>(0) * image.cols);
int y_center = static_cast<int>(row.at<float>(1) * image.rows);
int width = static_cast<int>(row.at<float>(2) * image.cols);
int height = static_cast<int>(row.at<float>(3) * image.rows);
int x_left = x_center - width / 2;
int y_top = y_center - height / 2;
class_ids.push_back(class_id.x);
confidences.push_back(confidence);
boxes.emplace_back(x_left, y_top, width, height);
}
}
}
std::vector<int> indices;
cv::dnn::NMSBoxes(boxes, confidences, confidence_threshold_, nms_threshold_, indices);
std::vector<cv::Rect> result;
for (int i : indices) {
result.push_back(boxes[i]);
}
return result;
}
private:
cv::dnn::Net net_;
float confidence_threshold_;
float nms_threshold_;
int input_width_;
int input_height_;
std::vector<std::string> class_names_;
std::vector<std::string> output_names_;
};
int main() {
std::string cfg_path = "/path/to/yolov4.cfg";
std::string weights_path = "/path/to/yolov4.weights";
std::vector<std::string> class_names = {"person", "car", "bicycle"};
YOLO detector(cfg_path, weights_path, 0.5, 0.5, 416, 416, class_names);
cv::Mat image = cv::imread("/path/to/image.jpg");
std::vector<cv::Rect> boxes = detector.detect(image);
for (const auto& box : boxes) {
cv::rectangle(image, box, cv::Scalar(0, 0, 255), 2);
}
cv::imshow("Detection Result", image);
cv::waitKey(0);
return 0;
}
```
在此示例中,YOLO类的构造函数接受YOLOv4的配置文件路径和权重文件路径,并可选地传递置信度阈值、NMS阈值、输入图像的宽度和高度以及类别名称列表。如果不传递类别名称列表,则默认使用COCO数据集的80个类别名称。
YOLO类的detect方法接受一个OpenCV Mat对象作为输入,并返回一个包含检测结果边界框的矩形向量。在主函数中,YOLO检测器创建并使用detect方法来检测输入图像中的目标,并在原始图像上绘制检测结果的边界框。
阅读全文