执行位置:模型开发实例中
yolov5仓库地址:https://github.com/XiaFire/cvmart-yolov5
下载该模型,并放置到/project/train/src_repo路径下,并改名为v5
文件放置位置:/project/train/src_repo/v5/yolov5/
文件内容:
cd /project/train/src_repo/v5/yolov5
# 安装环境
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple onnx onnx-simplifier
# 导出命令
python export.py \
--data data/cvmart.yaml \
--weights /project/train/models/exp5/weights/best.pt \
--simplify \
--include onnx
工具网址: https://netron.app
输出维度: box(x_center,y_center,width,height) + box_score + 类别信息
执行位置:算法开发实例
gitee仓库地址:https://gitee.com/cvmart/ev_sdk_demo4.0_pedestrian_intrusion_yolov5.git
cp -r ev_sdk_demo4.0_pedestrian_intrusion_yolov5/* ./ev_sdk/
"thresh": 0.01,
"mark_text_en": ["front_wear","front_no_wear","front_under_nose_wear","front_under_mouth_wear","front_unknown","side_wear","side_no_wear","side_under_nose_wear","side_under_mouth_wear","side_unknown","side_back_head_wear","side_back_head_no_wear","back_head","mask_front_wear","mask_front_under_nose_wear","mask_front_under_mouth_wear","mask_side_wear","mask_side_under_nose_wear","mask_side_under_mouth_wear","strap"],
"mark_text_zh": ["正面佩戴口罩包住鼻子","正面未佩戴口罩","正面佩戴口罩在鼻子下且在嘴巴上面","正面佩戴口罩在嘴巴下面","不能很明确知道正面是否佩戴口罩","侧面佩戴口罩包住鼻子","侧面未佩戴口罩","侧面佩戴口罩在鼻子下且在嘴巴上面","侧面佩戴口罩在嘴巴下面","不能很明确知道侧面是否佩戴口罩","带了口罩","没有戴口罩","背面人头","口罩包住鼻子","口罩在鼻子下且在嘴巴上面","口罩在嘴巴下面","口罩包住鼻子","口罩在鼻子下且在嘴巴上面","口罩在嘴巴下面","口罩的带子"],
struct Configuration
{
private:
Json::Value mJConfigValue;
public:
// 添加新变量alarmType、warningType
std::vector<int> alarmType = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};//定义需检测的类别
std::vector<int> warningType = {1,2,3,6,7,8};//定义需报警的类别
// 修改现有变量targetRectTextMap
std::map<std::string, std::vector<std::string> > targetRectTextMap = { {"en",{"front_wear","front_no_wear","front_under_nose_wear","front_under_mouth_wear","front_unknown","side_wear","side_no_wear","side_under_nose_wear","side_under_mouth_wear","side_unknown","side_back_head_wear","side_back_head_no_wear","back_head","mask_front_wear","mask_front_under_nose_wear","mask_front_under_mouth_wear","mask_side_wear","mask_side_under_nose_wear","mask_side_under_mouth_wear","strap"}}, {"zh", {"正面佩戴口罩包住鼻子","正面未佩戴口罩","正面佩戴口罩在鼻子下且在嘴巴上面","正面佩戴口罩在嘴巴下面","不能很明确知道正面是否佩戴口罩","侧面佩戴口罩包住鼻子","侧面未佩戴口罩","侧面佩戴口罩在鼻子下且在嘴巴上面","侧面佩戴口罩在嘴巴下面","不能很明确知道侧面是否佩戴口罩","带了口罩","没有戴口罩","背面人头","口罩包住鼻子","口罩在鼻子下且在嘴巴上面","口罩在嘴巴下面","口罩包住鼻子","口罩在鼻子下且在嘴巴上面","口罩在嘴巴下面","口罩的带子"}}};// 检测目标框顶部文字
//修改模型路径
STATUS SampleAlgorithm::Init(){
mDetector->Init("/usr/local/ev_sdk/model/yolov5s.onnx", mConfig.algoConfig.thresh);
}
//修改业务逻辑 将过滤出行人部分代码替换为以下代码
STATUS SampleAlgorithm::Process(const cv::Mat &inFrame, const char *args, JiEvent &event){
//过滤出目标
for(auto iter = detectedObjects.begin(); iter != detectedObjects.end();)
{
SDKLOG_FIRST_N(INFO, 5) << "iter->label : " << iter->label; //输出当前正在迭代的标签
if(find(mConfig.alarmType.begin(), mConfig.alarmType.end(), iter->label) != mConfig.alarmType.end())
{
iter++;
}
else
{
iter = detectedObjects.erase(iter);
}
}
// 过滤出有效目标
for (auto &obj : detectedObjects)
{
for (auto &roiPolygon : mConfig.currentROIOrigPolygons)
{
int mid_x = (obj.x1 + obj.x2) / 2;
int mid_y = (obj.y1 + obj.y2) / 2;
// 当检测的目标的中心点在ROI内的话,就视为闯入ROI的有效目标
if (WKTParser::inPolygon(roiPolygon, cv::Point(mid_x, mid_y)) && (find(mConfig.warningType.begin(), mConfig.warningType.end(), obj.label) != mConfig.warningType.end()))
{
validTargets.emplace_back(obj);
}
}
}
}
runNms(DetObjs, 0.05); //修改置信度
创建编译测试文件test.sh,并在算法开发 - 调试页运行该文件:
文件位置:与ev_sdk文件同级
文件内容:
# 删除已有的编译测试文件
rm -rf ./ev_sdk/build
rm -rf ./ev_sdk/test/build
# 编译SDK库
mkdir -p /usr/local/ev_sdk/build
cd /usr/local/ev_sdk/build
cmake ..
make install
# 编译测试工具
mkdir -p /usr/local/ev_sdk/test/build
cd /usr/local/ev_sdk/test/build
cmake ..
make install
# 测试
# /usr/local/ev_sdk/data/test1.jpeg 修改为自己的输入图片路径
# /usr/local/ev_sdk/data/result1.jpeg 修改为自己的输出图片路径
/usr/local/ev_sdk/bin/test-ji-api -f 1 -i /usr/local/ev_sdk/data/test1.jpeg -o /usr/local/ev_sdk/data/result1.jpeg
注意:每次修改代码后都需要删除之前的编译好的测试工具重新编译
1、可使用yolov5官方权重做预测,测试代码逻辑是否正确,需将类别0添加至报警类别,并使用包含多个人的图片作为输入图片,若可以检测到目标,则说明代码逻辑没有问题。
需修改如下代码:
mDetector->Init("/usr/local/ev_sdk/model/yolov5s.onnx", mConfig.algoConfig.thresh);
std::vector<int> alarmType = {0};
2、使用编码环境训练出的权重做测试,测试导出的onnx模型是否有问题,需使用编码环境中训练集相似的图片作为输入图片,且将置信度与之调整为0.01
需修改代码如下
"thresh": 0.01
mDetector->Init("/usr/local/ev_sdk/model/exp5/weights/best.onnx", mConfig.algoConfig.thresh);
std::vector<int> warningType = {1,2,3,6,7,8};
如使用官方封装代码,需修改src/SampleAlgorithm.cpp文件中的业务逻辑,具体代码如修改配置文件一节所示。
口罩识别任务需要输出20个类别检测信息,其中有6个类别需要报警,因此需要先筛选出20个类别的有效目标,再从其中筛选出6个类别的需报警的目标。