目录
以前写了一篇使用YOLOv4训练的博客:https://blog.csdn.net/Creama_/article/details/106209388。而后不少读者反映检测图片的结果中怎么没有置信度,怎么加?怎么改变检测框的粗细?框出来目标怎么保存到本地?等等。。。今天就先写一下这几部分的代码,但愿做者AlexeyAB看到给我打钱。函数
显示置信度
打开src/image.c
查找"draw_detections_v3",找到这个函数的定义部分,注意是定义部分。拉到函数最后一部分,只要在对应位置加上三句:
char buff[20];
sprintf(buff, "(%2.0f%%)", selected_detections[i].det.prob[selected_detections[i].best_class] * 100);
strcat(labelstr, buff);
便可,而后保存,从新make。
url
if (alphabet) { char labelstr[4096] = { 0 }; char buff[20]; //加上这句 strcat(labelstr, names[selected_detections[i].best_class]); sprintf(buff, "(%2.0f%%)", selected_detections[i].det.prob[selected_detections[i].best_class] * 100); //加上这句 strcat(labelstr, buff); //加上这句 int j; for (j = 0; j < classes; ++j) { if (selected_detections[i].det.prob[j] > thresh && j != selected_detections[i].best_class) { strcat(labelstr, ", "); strcat(labelstr, names[j]); } } image label = get_label_v3(alphabet, labelstr, (im.w*.01)); draw_label(im, top + width, left, label, rgb); free_image(label); }
改变检测框的粗细
打开src/image.c
查找"draw_detections_v3",找到函数定义部分,在函数体里找到"draw_box_width",其中变量width就是检测框的粗细。做者是这样定义的:
spa
int width = im.h * .002; if (width < 1) width = 1;
变大变小怎么变,你来定。.net
保存检测框的内容到本地
1.修改detector.c
这一部分是在增长了批量检测图片的基础上,将全部检测框中的内容保存到本地。批量检测图片在以前的博客有写。
打开src/detector.c
查找"test_detector",找到这个函数的定义部分,再找到里面的draw_detections_v3, 以下图所示:
命令行
这里有一部分是以前批量保存图片的代码,为了在画框以前保存检测框的内容,把获取文件名的代码放到了draw_detections_v3前面,而且在其后加上保存检测框中目标的代码:3d
save_dets(im, dets, nboxes, thresh, b);
2.修改image.h和image.c
打开src/image.h
在文件末尾加上函数save_dets的声明:
code
void save_dets(image im, detection *dets, int num_boxes, float thresh, const char* name);
以下图所示:
保存后打开src/image.c
在文件开头加入函数save_dets的定义:
blog
void save_dets(image im, detection *dets, int num_boxes, float thresh, const char* name){ int reg[4]; int width = im.w; int height = im.h; for(int i=0; i < num_boxes; ++i){ int best_class = -1; float best_class_prob = thresh; for (int j = 0; j < dets[i].classes; ++j){ if (dets[i].prob[j] > best_class_prob) { best_class = j; best_class_prob = dets[i].prob[j]; } } if (best_class >= 0){ box b = dets[i].bbox; reg[0] = round((b.x - b.w / 2) * width); reg[1] = round((b.y - b.h / 2) * height); reg[2] = round(b.w * width); reg[3] = round(b.h * height); if (reg[0] < 0) reg[0] = 0; if (reg[0] > width - 1) reg[0] = width - 1; if (reg[1] < 0) reg[1] = 0; if (reg[1] > height - 1) reg[1] = height - 1; if (reg[2] + reg[0] > width) reg[2] = width - reg[0]; if (reg[3] + reg[1] > height) reg[3] = height - reg[1]; save_dets_cv(im, reg, name, i); } } }
以下图所示:
图片
3.修改image_opencv.h和image_opencv.cpp
打开src/image_opencv.h
在文件末尾加上函数save_dets_cv的声明:
get
void save_dets_cv(image im, int reg[], const char* name, int i);
以下图所示:
保存后打开src/image_opencv.cpp
在文件末尾加上函数save_dets_cv的定义:
void save_dets_cv(image im, int reg[], const char* name, int i){ cv::Mat mat = image_to_mat(im); cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); cv::Mat dets = mat(cv::Rect(reg[0], reg[1], reg[2], reg[3])); //string name_dets = name; char name_dets[256]; sprintf(name_dets, "%s_dets%d.jpg", name, i); cv::imwrite(name_dets, dets); }
以下图所示:
到这里代码就写完了,保存全部文件,从新make。输入检测的命令行,结果会保存在output/,以下图所示,带dets的是每一个检测框中的内容,若是不想保存大图能够注释掉detector.c中的save_image。
由于C++学的不是很好,因此只能借助opencv的方法切片并保存,有更好的方法欢迎留言。