电动车进入电梯数据集、自行车进入电梯数据集 电动车进入电梯VOC数据标注数据集
一、项目来源
本项目作为一个小科研课题,分析当前电梯禁入电动车和自行车监控情况,搜集市场上的一些关键性,且有用的数据集,并对数据集进行了标注工作,数据集的格式声明:
数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件):
- 图片数量(jpg文件个数):7106
- 标注数量(xml文件个数):7106
- 标注数量(txt文件个数):7106
- 标注类别数:3
- 标注类别名称:["bicycle","motorcycle","person"]
- 每个类别标注的框数:
- bicycle 框数 = 489
- motorcycle 框数 = 5881
- person 框数 = 8224
- 总框数:14594
- 使用标注工具:labelImg
- 标注规则:对类别进行画矩形框
二、项目实施
1、数据展示:
2、数据训练:
数据训练采用yolov8,训练过程可以参考我的另一个博客:
yolov8的模型训练
训练过程:
3、训练结果:
4、算法部署 :
算法已经在windows和ubuntu的平台进行了部署工作,这里只对windows平台进行介绍:
工具准备:opencv4.9和Visual Studio Enterprise 2019
C++的检测代码如下,windows和ubuntu的区分标志为ON_M_WINDOWS:
代码的头文件:
#pragma once
#define ON_M_WINDOWS 1
#if ON_M_WINDOWS
#define AIM_DetectAPI_DLL __declspec(dllexport)
#endif
#define MAX_M_Detect_COUNT 200
#define MAX_M_POLY_POINT_COUNT 10
#define MAX_M_POLYS_COUNT 5
typedef void* AIM_Engine;
//错误信息标识
typedef enum
{
AI_ERROR_SUCESS = 0,//成功
AI_ERROR_NULLRETURN = 1, //空指针返回
AI_ERROR_SOFTDOG = 2, //加密狗异常
AI_ERROR_GPU_PROCESS, //GPU处理空间申请错误
AI_ERROR_MODELSPACE,//模型空间申请错误
AI_ERROR_RULESPARAMER,//规则参数错误
AI_ERROR_IMAGEPARAMER,//图像参数错误
AI_ERROR_IMAGE_FILE,图片路径参数错误
AI_ERROR_MODELPATH//模型路径错误
}AIM_Error;
typedef struct _AIM_PointF
{
float x;
float y;
}AIM_PointF;
typedef struct _AIM_Poly
{
int nPoints;
AIM_PointF points[MAX_M_POLY_POINT_COUNT];
}AIM_Poly;
typedef struct _AIM_InParam
{
int n_CameraID; //相机ID
int n_ImageID; //图像ID唯一
float f_Confidence; //检测到目标的置信度(0.0-1.0),默认0.5
int n_MinObjectSize; //检查的最小目标尺寸(取值范围:50-100010),默认100
int nPolyCount; //设置检测区域 其中nPolyCount=0,表示全图像分析
AIM_Poly polys[MAX_M_POLYS_COUNT];
}AIM_InParam;
typedef struct _AIM_InImage
{
int imageType; //0--bgrbgr...,1--rgbrgb...
int width; //图像宽 ,需要4的倍数
int height; //图像高
int channels; //图像通道数,只支持1-gray和3-rgb通道
char* data; //图像数据bgrbgr...
}AIM_InImage;
typedef struct _AIM_Rect
{
float f_Confidence; //检测到目标的置信度
int n_Type; //0-'bicycle', 1-'motorcycle',2-'person'
int n_Left; //目标rect--左上点x的相对坐标
int n_Right; //目标rect--左上点y的相对坐标
int n_Top; //目标rect--右下点x的相对坐标
int n_Bottom; //目标rect--右下点y的相对坐标
int n_CentreX; //rect 中心x
int n_CentreY; //rect 中心y
}AIM_Rect;
typedef struct _AIM_ResultInfo
{
int n_CameraID;//相机ID
int n_ImageID;//图像ID唯一
int n_ObjectCount;
AIM_Rect rects[MAX_M_Detect_COUNT];
}AIM_ResultInfo;
#ifdef __cplusplus
extern "C"
{
#endif
#if ON_M_WINDOWS
/******新接口调用*****
先创建一个算法句柄,
注:程序开始时只需调用一次
n_UseGPU; //cpu = 0,gpu需要N卡且需要重新编译opencv库,默认0 ---- 若申请GPU处理失败,会改用CPU处理
n_GPU_ID--指定在哪个GPU卡上运行(n_UseGPU设置为0时,该值不考虑),从0开始,如0,1,2....
pModel_Path; //文件名字为AIDetect.model
pError; //状态返回值,需要查看一下,看看模型和GPU是否错误
AIM_DetectAPI_DLL AIM_Engine AIM_EngineCreate(int n_UseGPU, int n_GPU_ID, char *pModel_Path, AIM_Error *pError);//先调用1
算法执行程序
pEngine算法句柄
inParam算法输入参数
outInfo算法输出参数
AIM_DetectAPI_DLL AIM_Error AIM_EngineImageFileAnalyze(AIM_Engine pEngine, AIM_InParam*inParam, AIM_InImage *pImage,AIM_ResultInfo *outInfo);//再调用2
算法销毁
注:程序结束时只需调用一次
AIM_DetectAPI_DLL AIM_Error AIM_EngineDestroy(AIM_Engine pEngine);//最后调用3
#else
/******新接口调用*****
先创建一个算法句柄,
注:程序开始时只需调用一次
AIM_Engine AIM_EngineCreate(int n_UseGPU, int n_GPU_ID, char* pModel_Path, AIM_Error* pError);//先调用1
算法执行程序
pEngine算法句柄
inParam算法输入参数
outInfo算法输出参数
AIM_Error AIM_EngineImageFileAnalyze(AIM_Engine pEngine, AIM_InParam* inParam, AIM_InImage* pImage, AIM_ResultInfo* outInfo);//再调用2
算法销毁
注:程序结束时只需调用一次
AIM_Error AIM_EngineDestroy(AIM_Engine pEngine);//最后调用3
#endif
#ifdef __cplusplus
}
#endif
算法的测试部分:
// AlgTest.cpp : Defines the entry point for the console application.
//
#include <fstream>
#include <sstream>
#include "opencv2/opencv.hpp"
#include "MotorcycleDetectAPI.h"
#if ON_M_WINDOWS
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <thread>
#include <vector>
#else
#include <chrono>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <dirent.h>
#include <unistd.h>
#endif
using namespace std;
using namespace cv;
AIM_Engine g_AIEngine;
#if ON_M_WINDOWS
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;
}
#else
int getFiles(char* path, std::vector<std::string>& files, std::vector<std::string>& names)
{
DIR* dir;
dir = opendir(path);
struct dirent* ptr;
files.clear();
while ((ptr = readdir(dir)) != NULL)
{
if (ptr->d_name[0] == '.') { continue; }
std::string fullpath = path;
fullpath = fullpath + ptr->d_name;
printf("path = %s\n", fullpath.c_str());
files.push_back(fullpath);
names.push_back(ptr->d_name);
}
closedir(dir);
return 0;
}
#endif
void imageTest(int argc, char *argv[])
{
AIM_Error error = AI_ERROR_SUCESS;
AIM_InParam inParam;
AIM_InImage inImage;
AIM_ResultInfo outInfo;
//使用前先初始化一下
memset(&inParam,0,sizeof(AIM_InParam));
memset(&inImage, 0, sizeof(AIM_InImage));
memset(&outInfo, 0, sizeof(AIM_ResultInfo));
//char* pClasses[5] = { "person", "car", "cat", "dog", "ladder" };
char* pClasses[3] = {"bicycle","motorcycle","person"};
std::vector<std::string> classes;
for (int i = 0; i < 1; i++)
{
classes.push_back(pClasses[i]);
}
//初始化函数句柄,可以在函数开始阶段创建多个句柄
g_AIEngine = AIM_EngineCreate(0, 0, "../bin/Moctorcycle.onnx", &error);//1
if (error != AI_ERROR_SUCESS)//注意是否返回异常
{
printf("error id = %d\n", error);
}
std::vector<std::string> files;
std::vector<std::string> names;
char* path = "./test/";
std::string save_path = "./result/";
getFiles(path, files, names);//加载文加下的图像路径
//对参数进行赋值
inParam.n_CameraID = 123456;
inParam.n_ImageID = 5678;
inParam.f_Confidence = 0.25;
inParam.n_MinObjectSize = 50;
inParam.nPolyCount = 0;
inParam.polys[0].nPoints = 4;
inParam.polys[0].points[0].x = 0.2;
inParam.polys[0].points[0].y = 0.2;
inParam.polys[0].points[1].x = 0.8;
inParam.polys[0].points[1].y = 0.2;
inParam.polys[0].points[2].x = 0.8;
inParam.polys[0].points[2].y = 0.8;
inParam.polys[0].points[3].x = 0.2;
inParam.polys[0].points[3].y = 0.8;
inParam.polys[1].nPoints = 5;
inParam.polys[1].points[0].x = 0.1;
inParam.polys[1].points[0].y = 0.2;
inParam.polys[1].points[1].x = 0.5;
inParam.polys[1].points[1].y = 0.2;
inParam.polys[1].points[2].x = 0.85;
inParam.polys[1].points[2].y = 0.15;
inParam.polys[1].points[3].x = 0.9;
inParam.polys[1].points[3].y = 0.9;
inParam.polys[1].points[4].x = 0.1;
inParam.polys[1].points[4].y = 0.9;
int i = 0, j = 0;
for (i = 0; i < files.size(); i++)
{
cv::Mat image = cv::imread(files[i]);
if (image.empty())
{
continue;
}
//对图像数据进行赋值
inImage.width = image.cols;
inImage.height = image.rows;
inImage.channels = image.channels();
inImage.data = (char*)image.data;
inImage.imageType = 0;
clock_t start, end;
float time;
start = clock();
//函数分析,基于函数句柄进行分析
int ret_Ana = AIM_EngineImageFileAnalyze(g_AIEngine, &inParam, &inImage, &outInfo);//2
printf("ret_Ana value = %d\n", ret_Ana);
end = clock();
time = (float)(end - start);//CLOCKS_PER_SEC;
printf("timeCount = %f\n", time);//测试时间
int step = 10;
for (int j = 0; j < outInfo.n_ObjectCount; j++)//结果解析
{
step = j*step;
AIM_Rect*rect = &outInfo.rects[j];
int txtLeft = rect->n_Left;
int txtTop = rect->n_Top + step;
txtTop = txtTop < 20 ? 20 : txtTop;
txtLeft = txtLeft < 20 ? 20 : txtLeft;
txtTop = txtTop > image.rows - 20 ? image.rows - 20 : txtTop;
txtLeft = txtLeft > image.cols - 20 ? image.cols - 20 : txtLeft;
if (0 == rect->n_Type)
{
cv::putText(image, pClasses[rect->n_Type], cv::Point(txtLeft, txtTop), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(0, 0, 255), 1);
rectangle(image, Point(rect->n_Left, rect->n_Top), Point(rect->n_Right, rect->n_Bottom), Scalar(0, 0, 255), 1, 8);
}
else if (1 == rect->n_Type)
{
cv::putText(image, pClasses[rect->n_Type], cv::Point(txtLeft, txtTop), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(0, 255, 0), 1);
rectangle(image, Point(rect->n_Left, rect->n_Top), Point(rect->n_Right, rect->n_Bottom), Scalar(0, 255, 0), 1, 8);
}
else if (2 == rect->n_Type)
{
cv::putText(image, pClasses[rect->n_Type], cv::Point(txtLeft, txtTop), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(0, 255, 255), 1);
rectangle(image, Point(rect->n_Left, rect->n_Top), Point(rect->n_Right, rect->n_Bottom), Scalar(0, 255, 255), 1, 8);
}
else if (3 == rect->n_Type)
{
cv::putText(image, pClasses[rect->n_Type], cv::Point(txtLeft, txtTop), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 255, 0), 1);
rectangle(image, Point(rect->n_Left, rect->n_Top), Point(rect->n_Right, rect->n_Bottom), Scalar(255, 255, 0), 1, 8);
}
else if (4 == rect->n_Type)
{
cv::putText(image, pClasses[rect->n_Type], cv::Point(txtLeft, txtTop), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 0, 255), 1);
rectangle(image, Point(rect->n_Left, rect->n_Top), Point(rect->n_Right, rect->n_Bottom), Scalar(255, 0, 255), 1, 8);
}
else
{
cv::putText(image, pClasses[rect->n_Type], cv::Point(txtLeft, txtTop), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(250, 11, 230), 1);
rectangle(image, Point(rect->n_Left, rect->n_Top), Point(rect->n_Right, rect->n_Bottom), Scalar(250, 11, 230), 1, 8);
}
}
cout << "image -- " << names[i] << " -- process OK!!!" << endl;
std::string save_name = save_path + names[i] + ".jpg";
cv::imwrite(save_name, image);
#if ON_WINDOWS
cv::Mat resieImage;
cv::resize(image, resieImage, cv::Size(image.cols, image.rows));
cv::imshow("image", resieImage);
cv::waitKey(100);
#endif
}
结束时销毁句柄
AIM_EngineDestroy(g_AIEngine);//3
}
int main(int argc, char *argv[])
{
imageTest(argc, argv);
return 0;
}
算法的工程测试部分截图:
5、小结
1)、算法vs2019使用时需要用release进行编译;
2)、里面封装了三个功能的检测算法,SDK链接如下:
https://download.csdn.net/download/zhulong1984/89937210
3)、数据集和源码可以私信我,也可以加QQ:187100248.