darknet分类网络,训练,C++调用分类器

2023-05-16

Darknet 分类器

出于对Darknet框架下YOLO结构的火热,网络上一堆关于目标检测的C++调用形式和模板,但是未曾存在C++调用分类器的模板,故采用如下形式,展开阐述。

Darknet出名的为目标检测网络,但是遗忘了其中的构建基础的分类网络方式,没有得到很好的利用
大致步骤可参考
训练过程和标注样本数据的方式参考如下文章:

https://blog.csdn.net/u011576009/article/details/70146766

中间出现的需要生成和修改的文件为,

数据集准备

train.list
格式为路径指向训练文件,/home/ubuntu/data/train/D250252_00001.jpg的形式
其中D250252为类别号
val.lilst
同train.list
label.list
只存在类别 如:D250252等
name.list
对类别号的映射过程,训练过程中不采用。

网络搭建

构建主要参考cifar 搭建了 lenet-5的分类网络,速度及其快,1080ti 1ms完成分类任务测试
需要更改为一个.cfg文件
一个data文件 指向训练集,测试集和类别号等等
跑网络使用的command

./darknet classifier train cfg/mnist.data cfg/mnist.cfg

测试单张图片

./darknet classifier predict cfg/market1501.data cfg/mobilenet_1501_train.cfg backup/mobilenet_1501_train_100.weights data/train/0007_aabbc1.jpg

测试Val数据集

./darknet classifier valid cfg/market1501.data cfg/mobilenet_1501_test.cfg backup/mobilet_v2/mobilenet_1501_train_787.weights

出现的Issue:
1、Train的过程中出现Too many or too few arguments
参考github中issues:
https://github.com/pjreddie/darknet/issues/833

  • 修改了源码,但是测试过程,还是出现分类报错问题
    fill_truth function in src/data.c file
void fill_truth(char *path, char **labels, int k, float *truth)
 {
     int i;
     char *filename = "";
     for (i = strlen(path) - 1; i >= 0; --i) {
         if (path[i] == '/' || path[i] == '\\') {
             filename = (char*)malloc(strlen(path + i) + 1);
             strcpy(filename, path + i + 1);
             break;
         }
     }
     memset(truth, 0, k*sizeof(float));
     int count = 0;
     for(i = 0; i < k; ++i){
         if(strstr(filename, labels[i])){
             truth[i] = 1;
             ++count;
             //printf("%s %s %d\n", path, labels[i], i);
         }
     }
     if(count != 1 && (k != 1 || count != 0)) printf("Too many or too few labels: %d, %s\n", count, path);
 }
  • 后参考另一个issues
    提及到,路径和类别不能出现一样的字符,将会导致判定失误,改完以后,成功完成训练过程。

C++调用方式

使用编译完成libdarnet.so配合cuda的动态库,再加头文件darknet.h 即可调用
主要关键使用在于分类网络的输出问题,网络的输入采用接口的形式
主要参考代码为darknet源码中cuda.c classfier.c darnet.c等内容
参考Yolo调用模板格式:
https://blog.csdn.net/weixin_33860450/article/details/84890877
其中较为关键的是img_preprocess 问题
imgprocess.hpp

#ifndef IMPROCESS_H
#define IMPROCESS_H
 
#include<opencv2/opencv.hpp>
 
void imgConvert(const cv::Mat& img, float* dst);
 
void imgResize(float* src, float* dst,int srcWidth,int srcHeight,int dstWidth,int dstHeight);
 
void resizeInner(float *src, float* dst,int srcWidth,int srcHeight,int dstWidth,int dstHeight);
 
#endif // IMPROCESS_H

imgprocess.cpp

#include<improcess.h>
 
void imgConvert(const cv::Mat& img, float* dst){
    uchar *data = img.data;
    int h = img.rows;
    int w = img.cols;
    int c = img.channels();
 
    for(int k= 0; k < c; ++k){
        for(int i = 0; i < h; ++i){
            for(int j = 0; j < w; ++j){
                dst[k*w*h+i*w+j] = data[(i*w + j)*c + k]/255.;
            }
        }
    }
}
 
void imgResize(float *src, float* dst,int srcWidth,int srcHeight,int dstWidth,int dstHeight){
    int new_w = srcWidth;
    int new_h = srcHeight;
    if (((float)dstWidth/srcWidth) < ((float)dstHeight/srcHeight)) {
        new_w = dstWidth;
        new_h = (srcHeight * dstWidth)/srcWidth;
    } else {
        new_h = dstHeight;
        new_w = (srcWidth * dstHeight)/srcHeight;
    }
 
    float* ImgReInner;
    size_t sizeInner=new_w*new_h*3*sizeof(float);
    ImgReInner=(float*)malloc(sizeInner);
    resizeInner(src,ImgReInner,srcWidth,srcHeight,new_w,new_h);
 
    for(int i=0;i<dstWidth*dstHeight*3;i++){
        dst[i]=0.5;
    }
 
    for(int k = 0; k < 3; ++k){
        for(int y = 0; y < new_h; ++y){
            for(int x = 0; x < new_w; ++x){
                float val = ImgReInner[k*new_w*new_h+y*new_w+x];
                dst[k*dstHeight*dstWidth + ((dstHeight-new_h)/2+y)*dstWidth + (dstWidth-new_w)/2+x]=val;
            }
        }
    }
    free(ImgReInner);
}
 
void resizeInner(float *src, float* dst,int srcWidth,int srcHeight,int dstWidth,int dstHeight){
    float* part;
    size_t sizePa=dstWidth*srcHeight*3*sizeof(float);
    part=(float*)malloc(sizePa);
 
    float w_scale = (float)(srcWidth - 1) / (dstWidth - 1);
    float h_scale = (float)(srcHeight - 1) / (dstHeight - 1);
 
    for(int k = 0; k < 3; ++k){
        for(int r = 0; r < srcHeight; ++r){
            for(int c = 0; c < dstWidth; ++c){
                float val = 0;
                if(c == dstWidth-1 || srcWidth == 1){
                    val=src[k*srcWidth*srcHeight+r*srcWidth+srcWidth-1];
                } else {
                    float sx = c*w_scale;
                    int ix = (int) sx;
                    float dx = sx - ix;
                    val=(1 - dx) * src[k*srcWidth*srcHeight+r*srcWidth+ix] + dx * src[k*srcWidth*srcHeight+r*srcWidth+ix+1];
                }
                part[k*srcHeight*dstWidth + r*dstWidth + c]=val;
            }
        }
    }
 
    for(int k = 0; k < 3; ++k){
        for(int r = 0; r < dstHeight; ++r){
            float sy = r*h_scale;
            int iy = (int) sy;
            float dy = sy - iy;
            for(int c = 0; c < dstWidth; ++c){
                float val = (1-dy) * part[k*dstWidth*srcHeight+iy*dstWidth+c];
                dst[k*dstWidth*dstHeight + r*dstWidth + c]=val;
            }
            if(r == dstHeight-1 || srcHeight == 1)
                continue;
            for(int c = 0; c < dstWidth; ++c){
                float val = dy * part[k*dstWidth*srcHeight+(iy+1)*dstWidth+c];
                dst[k*dstWidth*dstHeight + r*dstWidth + c]+=val;
            }
        }
    }
    free(part);
}

main.cpp(模板如下)

network *net = load_network();
// img pre process  resize ,convert malloc space
float *predictions = network_predict(*net,resizeImg);
top_k(predictions,(*net).outputs,top,indexes);
//output the index 
int  index = indexes[0];
predictions[index];

参考形式如下形式:把yolo的输出形式换成上述模板内容,即可完成分类预测任务。

#include<iostream>
#include<opencv2/opencv.hpp>
#include<darknet.h>
#include<improcess.h>
 
using namespace std;
using namespace cv;
 
float colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} };
 
float get_color(int c, int x, int max){
    float ratio = ((float)x/max)*5;
    int i = floor(ratio);
    int j = ceil(ratio);
    ratio -= i;
    float r = (1-ratio) * colors[i][c] + ratio*colors[j][c];
    return r;
}
 
 
int main()
{
    string cfgfile = "/home/chnn/darknet/cfg/yolov3.cfg";//读取模型文件,请自行修改相应路径
    string weightfile = "/home/chnn/darknet/yolov3.weights";
    float thresh=0.5;//参数设置
    float nms=0.35;
    int classes=80;
 
    network *net=load_network((char*)cfgfile.c_str(),(char*)weightfile.c_str(),0);//加载网络模型
    set_batch_network(net, 1);
    VideoCapture capture("/home/chnn/video/videoCapture6.mp4");//读取视频,请自行修改相应路径
    Mat frame;
    Mat rgbImg;
 
    vector<string> classNamesVec;
    ifstream classNamesFile("/home/chnn/darknet/data/coco.names");//标签文件coco有80类
 
    if (classNamesFile.is_open()){
        string className = "";
        while (getline(classNamesFile, className))
            classNamesVec.push_back(className);
    }
 
    bool stop=false;
    while(!stop){
        if (!capture.read(frame)){
            printf("fail to read.\n");
            return 0;
        }
        cvtColor(frame, rgbImg, cv::COLOR_BGR2RGB);
 
        float* srcImg;
        size_t srcSize=rgbImg.rows*rgbImg.cols*3*sizeof(float);
        srcImg=(float*)malloc(srcSize);
 
        imgConvert(rgbImg,srcImg);//将图像转为yolo形式
 
        float* resizeImg;
        size_t resizeSize=net->w*net->h*3*sizeof(float);
        resizeImg=(float*)malloc(resizeSize);
        imgResize(srcImg,resizeImg,frame.cols,frame.rows,net->w,net->h);//缩放图像
 
        network_predict(net,resizeImg);//网络推理
        int nboxes=0;
        detection *dets=get_network_boxes(net,rgbImg.cols,rgbImg.rows,thresh,0.5,0,1,&nboxes);
 
        if(nms){
            do_nms_sort(dets,nboxes,classes,nms);
        }
 
        vector<cv::Rect>boxes;
        boxes.clear();
        vector<int>classNames;
 
        for (int i = 0; i < nboxes; i++){
            bool flag=0;
            int className;
            for(int j=0;j<classes;j++){
                if(dets[i].prob[j]>thresh){
                    if(!flag){
                        flag=1;
                        className=j;
                    }
                }
            }
            if(flag){
                int left = (dets[i].bbox.x - dets[i].bbox.w / 2.)*frame.cols;
                int right = (dets[i].bbox.x + dets[i].bbox.w / 2.)*frame.cols;
                int top = (dets[i].bbox.y - dets[i].bbox.h / 2.)*frame.rows;
                int bot = (dets[i].bbox.y + dets[i].bbox.h / 2.)*frame.rows;
 
                if (left < 0)
                    left = 0;
                if (right > frame.cols - 1)
                    right = frame.cols - 1;
                if (top < 0)
                    top = 0;
                if (bot > frame.rows - 1)
                    bot = frame.rows - 1;
 
                Rect box(left, top, fabs(left - right), fabs(top - bot));
                boxes.push_back(box);
                classNames.push_back(className);
            }
        }
        free_detections(dets, nboxes);
 
        for(int i=0;i<boxes.size();i++){
            int offset = classNames[i]*123457 % 80;
            float red = 255*get_color(2,offset,80);
            float green = 255*get_color(1,offset,80);
            float blue = 255*get_color(0,offset,80);
 
            rectangle(frame,boxes[i],Scalar(blue,green,red),2);
 
            String label = String(classNamesVec[classNames[i]]);
            int baseLine = 0;
            Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
            putText(frame, label, Point(boxes[i].x, boxes[i].y + labelSize.height),
                    FONT_HERSHEY_SIMPLEX, 1, Scalar(red, blue, green),2);
        }
        imshow("video",frame);
 
        int c=waitKey(30);
              if((char)c==27)
                  break;
              else if(c>=0)
                  waitKey(0);
 
        free(srcImg);
        free(resizeImg);
    }
    free_network(net);
    capture.release();
    return 1;
}
 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

darknet分类网络,训练,C++调用分类器 的相关文章

  • MQTT协议简介

    目录 MQTT协议简介一 MQTT协议特点1 1 发布和订阅1 2 QoS Quality of Service levels 二 MQTT数据包结构2 1 MQTT固定头2 2 MQTT可变长 Variable header 2 3 消息
  • vins位姿图优化

    我们 的滑动窗口和边缘化方案限制了计算的复杂性 xff0c 但也给系统带来了累积漂移 更确切地说 xff0c 漂移发生在全局三维位置 x y z 和围绕重力方向的旋转 yaw 为了消除漂移 xff0c 提出了一种与单目VIO无缝集成的紧耦合
  • 基于STM32开发板实现温湿度传感数据采集

    一 实验要求 本实验将选用STM32F407ZGT6开发板进行项目开发 xff0c 选用的传感器为DHT11温湿度传感器 传感器将采集到的数据传输到STM32 xff08 MCU xff09 主控进行数据处理 xff0c 最后通过串口打印出
  • 相机成像模型、内参矩阵、外参矩阵

    相机针孔成像模型 基本的小孔成像过程 xff1a X坐标系是针孔所在坐标系 xff0c Y坐标系为成像平面坐标系 xff0c P为空间一点 xff0c 小孔成像使得P点在图像平面上呈现了一个倒立的像 xff0c 俯视图如下 xff1a 由三
  • 韦东山学习笔记——UART(串口)的使用

    基于jz2440的串口使用 搬砖的文章概述UART的发送和接收串口之间的数据传输UART的用途串口的数据帧参数说明起始位数据位奇偶校验位停止位波特率 怎么发送一字节数据 xff0c 比如 A UART的优缺点优点缺点 UART相关配置寄存器
  • C++源文件的编译流程简介

    概述 C 43 43 C源文件 xff0c 包含 c h cpp hpp等格式的文件 xff0c 经过预处理 编译 汇编 链接后 xff0c 形成可执行文件 xff0c 也就是 exe文件 以一个简单项目MyProject为例 xff0c
  • 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系

    使用 sudo apt get install 安装软件时 xff0c 出现错误 无法修正错误 xff0c 因为您要求某些软件包保持现状 xff0c 就是它们破坏了软件包间的依赖关系 错误的主要原因是 xff0c 系统中已经安装了被依赖的包
  • kalibr工具的编译与安装

    安装 kalibr提供了两种安装使用的方法 一 直接使用打包好的程序 下载地址 xff0c 选择CDE packages下载 xff08 需要访问Google xff09 使用注意事项 xff1a 只有64位系统可以使用 二 源码编译 安装
  • TCP/IP协议栈协议头

    目录 OSI与TCP IP模型UDP发送数据过程以太网协议头IP协议头UDP协议头UDP包 OSI与TCP IP模型 UDP发送数据过程 以太网协议头 把上面的以太网头用一个结构体表示如下 xff1a span class token ma
  • VLAN标签

    大家好呀 xff0c 我是请假君 xff0c 今天又来和大家一起学习数通了 xff0c 今天要分享的知识是VLAN标签 我们知道 xff0c 以太网交换机根据MAC地址表来转发数据帧 MAC地址表中包含了端口和端口所连接终端主机MAC地址的
  • fastjson的一些用法

    一般情况下 xff0c 在进行redis集群写入时 xff0c 使用jedisCluster set key value value为String类型 xff0c 那么就用到了fastjson进行序列化 以下是一些要点 xff1a 1 序列
  • 【视觉SLAM十四讲】第12讲 回环检测

    12 1 回环检测概述 前面已经介绍过了前端和后端 xff0c 前端用于特征点的提取以及轨迹 地图的初始值 xff0c 而后端负责对这部分数据进行优化 考虑到误差的存在 xff0c 每一个时刻存在的误差会不断累积 xff0c 从而产生累积误
  • LVGL——PC模拟器仿真模拟+VS2017

    目录 LVGL介绍移植说明资源下载环境搭建编译运行 本文只针对当时的LVGL v7 xff0c LVGL迭代过程中变化较大 xff0c 部分接口有可能做调整 本文仅供参考 LVGL介绍 官网 xff1a https lvgl io 官方在线
  • LVGL 优化帧率技巧

    目录标题 前文未优化版本LVGL帧率限制刷屏方法效率代码优化等级编译器版本LVGL显存单buffer非全尺寸双buffer全尺寸双buffer 本文只针对当时的LVGL v7 xff0c LVGL迭代过程中变化较大 xff0c 部分接口有可
  • CMAKE 里PRIVATE、PUBLIC、INTERFACE属性示例详解

    闲扯 cmake 里面target include directories xff0c target link libraries这两个命令里面有三种属性PRIVATE PUBLIC INTERFACE cmake PRIVATE PUBL
  • C++11 返回值优化、移动语义及函数返回值构造的重载决议

    局部变量unique ptr能否作为返回值 记得自己之前在哪写过一篇返回值优化的博客 xff0c 翻了半天csdn xff0c 居然没找到 xff0c 也不知道写在哪了 被问到一个unique ptr 局部变量能不能做返回值的问题 xff0
  • C++ 面试八股分享

    一年半 xff0c 估计又要跳槽了 xff0c 本来还想再积累一两年的 xff0c 结果公司业务线调整 xff0c 同部门三四个同事n 43 1裁了 xff0c 我也要换工作内容 xff0c 现在在来这么一出 xff0c 就准备骑驴找马 x
  • c++ makefile + clangd 生成 compile_command.json

    补充vscode 43 clangd 开发 c c 43 43 一个项目用makefile管理 xff0c 工程很大 xff0c vscode的ms cpp tools代码跳转功能基本处于残废状态 xff0c 有想将makefile 迁移至
  • stm32 串口+DMA+环形FIFO缓存收发数据

    cos环境例程 freertos环境例程 重要几点 1 配置DMA xff0c 串口及环形buff之间的关系 xff1b 2 USART IT IDLE空闲中断接收完一帧数据 xff0c 处理环形buff入口指针 通知用户程序接收完一次数据
  • VScode 中 C或C++ 结构体提示,代码补全不准确的 解决方案

    1 找到项目工作区的 settings json文件 2 修改 C Cpp intelliSenseEngine Tag Parser 为 C Cpp intelliSenseEngine Default 解释 Tag Parser 提供非

随机推荐

  • C/C++ 避免重复定义

    加入宏定义 第一种 xff1a span class token macro property span class token directive keyword ifndef span STUDENT H span span class
  • vscode文件标签栏显示多行

    设置步骤 xff1a 按下 ctrl 43 shift 43 p xff0c 如下图 xff1a 输入 open workspace settings xff0c 打开工作区设置 输入 workbench editor wrapTabs x
  • ::在C++中的意思

    表示作用域 xff0c 和所属关系 class A int A test 表示test是属于A类的 关于 的具体解析 xff1a 是运算符中等级最高的 xff0c 它分为三种 1 global scope 全局作用域符 xff09 xff0
  • 【Linux问题解决】操作系统用C语言多线程编程 对‘pthread_create’未定义的引用 报错解决办法

    操作系统用C语言多线程编程 对 pthread create 未定义的引用 报错解决办法 今天写操作系统作业 在Ubuntu Linux系统中用C语言编写多线程程序 在命令行进行编译 没通过编译 报错如下 xff1a In file inc
  • linux 服务器执行post请求 curl命令详解

    什么是curl xff1f curl是一个命令行访问URL的计算机逻辑语言的工具 xff0c 发出网络请求 xff0c 然后得到数据并提取出 xff0c 显示在标准输出 stdout 上面 xff0c 可以用它来构造http request
  • open-falcon 监控cpu指标及含义

    user 30512019 从系统启动开始累计到当前时刻 xff0c 用户态的CPU时间 xff0c 不包含nice值为负进程 nice 2905 从系统启动开始累计到当前时刻 xff0c nice值为负的进程所占用的CPU时间 syste
  • [Unity] 串口读取数据错误 IOException: 拒绝访问。

    错误内容 IOException 拒绝访问 System IO Ports WinSerialStream ReportIOError System String optional arg at lt 14e3453b740b4bd690e
  • px4仿真无法起飞问题(Failsafe enabled: no datalink)

    报错信息 问题描述 xff1a 使用JMAVSim和gazebo仿真px4起飞时报错如下 xff1a WARN commander Failsafe enabled no datalink 说不安全 解决方法 打开QGC 就可以起飞了
  • TCP (传输控制协议)和 UDP

    传输控制协议 xff08 TCP xff0c Transmission Control Protocol xff09 是一种面向连接的 可靠的 基于字节流的传输层通信协议 是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输
  • 全网第一篇 Jetson AGX Xaiver + Jetpack5.0.2(Ubuntu20.04) + ROS2 + ORB-SLAM3 + ZED2

    本机系统 xff1a Jetpack5 0 2 Ubuntu 20 04 LTS 注意事项 xff1a 想要避坑 xff0c 务必按照文中版本准备各种环境 一 安装软件 1 Pangolin 0 5 网址 xff1a https githu
  • java中char转化为int的几种方法

    java中char转化为int的几种方法总结 方法一 xff1a 在char后面 0 span class token keyword public span span class token keyword class span span
  • 大疆 RoboMaster 3508/2006/GM6020 电机使用教程

    19年开始使用大疆的电机 xff0c 刚开始接触有很多东西不懂 xff0c 网上除了RM官网提供的一些资料外没有很多其他的资料 xff0c 现在使用大疆电机近一年了 xff0c 想分享一下自己的经验 1 硬件部分 1 C610电调只能连接M
  • DBC文件解析及CAN通信矩阵

    一般的 DBC 文件中包含了如下的8种信息 xff1a 1 版本与新符号 2 波特率定义 3 网络节点的定义 4 报文帧的定义 5 信号的定义 6 注解部分 7 特征部分 8 数值表部分 VERSOIN 34 34 版本信息 xff0c 为
  • 基于Rplidar二维雷达使用Hector_SLAM算法在ROS中建图

    文章目录 前言一 ROS分布式通信 xff08 配置多机通信 xff09 1 简介2 步骤2 1 准备2 2 修改配置文件2 3配置主机IP2 4配置从机IP 二 RPlidar的使用教程1 创建环境2 下载激光雷达的功能包3 编译4 启动
  • TCP连接建立的步骤

    TCP连接建立的步骤 一 客户端向服务器端发送连接请求后 xff0c 就被动地等待服务器的响应 典型的TCP客户端要经过下面三步操作 xff1a 1 创建一个Socket实例 xff1a 构造函数向指定的远程主机和端口建立一个TCP连接 x
  • 能否在头文件中放置函数定义?

    语法上是可以这样做的 xff0c 但是在编程规范中并不鼓励这样做 成员函数一般是不可以在头文件中定义的 xff0c 只能在头文件中声明 因为函数只能有一次定义 xff0c 而可以有多次声明 xff0c 当头文件被多次包含的时候 xff0c
  • 万能的sprintf

    0 前言 先推荐一本书 xff0c 政治书籍 政治的人生 xff0c 算是一本日记题材 是现任 xff0c 作者大家百度一下就知道了 xff0c 这里不宜过多说明 从这本书里 xff0c 可以看出来现在的社会 这本书是30年前的 大佬就是大
  • 串口通讯UART/RS232/RS485/RS-422笔记

    串口通讯详解笔记 串口通讯概述串口通讯传输数据帧的结构UARTRS232RS485RS 422RS 232 RS 422和RS 485的主要区别 xff08 重要 xff09 串口通讯概述 串口通讯是指数据按位 xff08 bit xff0
  • Stm32 hal库 usart2与hc-08透传模块通讯

    Stm32 hal库 usart2与hc 08透传模块通讯 xff08 附数据解析 xff09 一 stm32cubeMX配置 1 配置RCC为外部晶振 2 配置时钟树 3 配置usart1 usart2 xff0c 其中usart1将作为
  • darknet分类网络,训练,C++调用分类器

    Darknet 分类器 出于对Darknet框架下YOLO结构的火热 xff0c 网络上一堆关于目标检测的C 43 43 调用形式和模板 xff0c 但是未曾存在C 43 43 调用分类器的模板 xff0c 故采用如下形式 xff0c 展开