使用 C 语言实现物体检测(YOLO)

news/2024/12/2 19:25:57/文章来源:https://www.cnblogs.com/ocr12/p/18582513

物体检测是计算机视觉中的核心任务之一。在这篇文章中,我们将使用 C 语言结合 OpenCV 和 YOLO 模型,展示如何在图像中检测物体的位置。YOLO(You Only Look Once)是一种高效的深度学习模型,广泛应用于物体检测任务。虽然 C 语言本身不具备深度学习库,但 OpenCV 提供了足够的支持来加载、处理和推理图像。

环境准备

  1. 安装 OpenCV
    首先,我们需要安装 OpenCV 库,以便能够加载图像并处理其内容。在 Ubuntu 系统上,你可以使用以下命令安装 OpenCV:

bash
更多内容访问ttocr.com或联系1436423940
sudo apt-get update
sudo apt-get install libopencv-dev
2. 获取 YOLO 模型文件
下载 YOLOv3 的配置文件和预训练权重文件(yolov3.cfg 和 yolov3.weights)。此外,还需要一个标签文件(coco.names),该文件包含 YOLO 能够检测的物体类别。

你可以从 YOLO 的官方网站下载这些文件:

YOLOv3 cfg 文件
YOLOv3 预训练权重
COCO 标签文件
编写 C 语言代码

  1. 初始化 OpenCV 和 YOLO 模型
    我们将加载 YOLO 模型,并使用 OpenCV 进行物体检测。以下是使用 C 语言调用 YOLO 模型进行物体检测的示例代码:

c

include <opencv2/opencv.hpp>

include <opencv2/dnn.hpp>

include

include

include

using namespace cv;
using namespace std;

// 函数:读取 COCO 标签文件
vector loadClassNames(const string &filename) {
vector classNames;
ifstream ifs(filename);
string line;
while (getline(ifs, line)) {
classNames.push_back(line);
}
return classNames;
}

// 函数:绘制检测框
void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat &frame, const vector &classNames) {
rectangle(frame, Point(left, top), Point(right, bottom), Scalar(0, 255, 0), 2);
string label = format("%.2f", conf);
if (!classNames.empty()) {
label = classNames[classId] + ":" + label;
}
putText(frame, label, Point(left, top - 5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 2);
}

int main(int argc, char** argv) {
// 检查输入参数
if (argc != 2) {
cerr << "Usage: ./yolo_detector <image_file>" << endl;
return -1;
}

// 加载 YOLO 模型
String modelConfiguration = "yolov3.cfg";
String modelWeights = "yolov3.weights";
String classFile = "coco.names";// 加载网络和类名
vector<string> classNames = loadClassNames(classFile);
Net net = readNetFromDarknet(modelConfiguration, modelWeights);// 加载图片
Mat frame = imread(argv[1]);
if (frame.empty()) {cerr << "Image not found!" << endl;return -1;
}// 处理图片,创建 Blob
Mat blob;
blobFromImage(frame, blob, 1.0 / 255.0, Size(416, 416), Scalar(0, 0, 0), true, false);
net.setInput(blob);// 获取 YOLO 网络的输出层
vector<Mat> outs;
vector<String> outNames = net.getUnconnectedOutLayersNames();
net.forward(outs, outNames);// 分析网络输出,进行物体检测
vector<int> classIds;
vector<float> confidences;
vector<Rect> boxes;
for (size_t i = 0; i < outs.size(); ++i) {float* data = (float*)outs[i].data;for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols) {Mat scores = outs[i].row(j).colRange(5, outs[i].cols);Point classIdPoint;double confidence;minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);if (confidence > 0.5) {int centerX = (int)(data[0] * frame.cols);int centerY = (int)(data[1] * frame.rows);int width = (int)(data[2] * frame.cols);int height = (int)(data[3] * frame.rows);int left = centerX - width / 2;int top = centerY - height / 2;classIds.push_back(classIdPoint.x);confidences.push_back((float)confidence);boxes.push_back(Rect(left, top, width, height));}}
}// 非最大值抑制
vector<int> indices;
NMSBoxes(boxes, confidences, 0.5, 0.4, indices);// 绘制结果
for (size_t i = 0; i < indices.size(); ++i) {int idx = indices[i];drawPred(classIds[idx], confidences[idx], boxes[idx].x, boxes[idx].y,boxes[idx].x + boxes[idx].width, boxes[idx].y + boxes[idx].height, frame, classNames);
}// 显示结果
imshow("Detected Objects", frame);
waitKey(0);return 0;

}
2. 编译并运行程序
编译命令
确保你已安装 OpenCV 并配置好 CMake 或者直接使用命令行进行编译。

bash

g++ -o yolo_detector yolo_detector.cpp pkg-config --cflags --libs opencv4
运行程序

./yolo_detector test.jpg
3. 代码解释
加载 YOLO 模型:

使用 cv::dnn::readNetFromDarknet() 函数加载 YOLO 配置文件和权重文件,构建网络。
图像预处理:

使用 blobFromImage() 函数将输入图像转换为网络所需的输入格式。
推理:

使用 net.forward() 函数进行前向推理,获取检测结果。
解析输出:

解析 YOLO 输出的 bounding box 信息,包括物体的类别、置信度、位置等。
非最大抑制(NMS):

使用 cv::dnn::NMSBoxes() 函数去除多余的重叠框,确保检测结果清晰。
绘制结果:

使用 rectangle() 和 putText() 函数在图像上绘制物体框,并标注物体类别和置信度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/845575.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用服务器docker搭建Pwn题目

一、docker的安装 1、安装前先卸载操作系统默认安装的docker sudo apt-get remove docker docker-engine docker.io containerd runc 2、安装必要支持 sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release 3、添加gpg KE…

Windows系统下通过命令行获取进程指标

1.获取当前ProcessID。GetCurrentProcess2.执行cmd或PowerShell cmd:wmic process where "processid=15844" get /format:list PowerShell:Get-Process -id 15844 | Format-List * 作者:快雪 出处:http://www.cnblogs.com/kuaixue/ 本文版权归作者所有,欢迎转…

各层协议

原文链接:点我

技术框架中ORM概念和原理的学习

ORM概念和原理 ORM 概念 我们在介绍 MyBatis 时说到,MyBatis是一种半自动 ORM 实现。那何为 ORM,何为半自动? ORM(Object/Relation Mapping,对象/关系数据库映射)是一种描述对象与关系数据库之间映射的规范。 ORM 作用Java对象和关系数据库如同马和牛,简直是牛头不对马嘴…

在华为开发者空间,基于鲲鹏服务器快速开发打砖块小游戏

本案例将指导开发者如何在鲲鹏服务器部署并运行web小游戏。本文分享自华为云社区《基于鲲鹏服务器的打砖块小游戏部署》,作者: 开发者空间小蜜蜂。 1.1 案例介绍 鲲鹏服务器是基于鲲鹏处理器的新一代数据中心服务器,适用于大数据、分布式存储、高性能计算和数据库等应用。鲲…

5-文件上传漏洞

1、文件上传漏洞原理 1.1 一句话木马 <?php @eval($_POST[xu]); ?> 其中@表示忽略错误,eval()函数表示把传进去的字符串作为php代码执行 从http post里面拿到参数叫xu的value,然后作为代码去执行,并忽略错误 2、Webshell介绍 一句话木马、大马、小马、图片马都是web…

纯血鸿蒙进程加速,混合app开发迎来又一波新机会

对于开发者来说,未来相当一段时间,将来会为鸿蒙,安卓,IOS三个系统同时开发APP上架,其中面对全新的鸿蒙系统,百万APP在未来几年会重新开发上架。 鸿蒙SDK厂商及App开发团队,迎来新的市场机遇。时间不知不觉又来到了2024年最后一个月,又到了辞旧迎新,复盘今年,放眼明年…

实验五 继承和多态

实验一: 代码: publisher.hpp:1 #pragma once2 3 #include<iostream>4 #include<string>5 6 using std::cout;7 using std::endl;8 using std::string;9 10 class Publisher { 11 public: 12 Publisher(const string& s = ""); 13 14 public…

博客园-添加统计图

💖简介 通过WPS在线列表构建博客园每日相关数据统计图。 👉效果📖实现前往WPShttps://www.kdocs.cn/latest新建多维表格 创建表格视图新建仪表盘 新建卡片、折线图卡片配置示例折线图配置示例点击分享获取链接⭐链接配置在config中配置link{icon: <svg t="173313…

华为技术专家出品,《华为开发者空间案例指南》带你玩转云上20+场景应用开发

免费领取云主机,开启你的云上开发之旅,分享体验将有机会赢取精美礼品。 关键词:开发者空间、AI、鲲鹏、Serverless随时随地都能开启开发之旅,这是一种怎样奇妙的体验?想象一下,无需安装繁琐的 IDE,也不用搭建复杂的开发环境,只需开机,就能迅速投入项目开发。在华为开发…

jQuery和CSS3折叠卡片式下拉列表框特效

这是一款使用JQUERY和CSS3制作的效果非常炫酷的折叠卡片式下拉列表框特效。该下拉列表框特效将每一个列表项都制作为卡片的样式,打开和关闭它有打开和关闭百叶窗的感觉,效果非常不错。预览 下载使用方法HTML结构 该下拉列表框特效的列表项使用一个无序列表来制作,用于切换…