目录
之前写了一篇使用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。
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就是检测框的粗细。作者是这样定义的:
int width = im.h * .002;
if (width < 1)
width = 1;
变大变小怎么变,你来定。
保存检测框的内容到本地
1.修改detector.c
这一部分是在增加了批量检测图片的基础上,将所有检测框中的内容保存到本地。批量检测图片在之前的博客有写。
打开src/detector.c
查找"test_detector",找到这个函数的定义部分,再找到里面的draw_detections_v3, 如下图所示:
这里有一部分是之前批量保存图片的代码,为了在画框之前保存检测框的内容,把获取文件名的代码放到了draw_detections_v3前面,并且在其后加上保存检测框中目标的代码:
save_dets(im, dets, nboxes, thresh, b);
2.修改image.h和image.c
打开src/image.h
在文件末尾加上函数save_dets的声明:
void save_dets(image im, detection *dets, int num_boxes, float thresh, const char* name);
如下图所示:
保存后打开src/image.c
在文件开头加入函数save_dets的定义:
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的声明:
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的方法切片并保存,有更好的方法欢迎留言。
来源:oschina
链接:https://my.oschina.net/u/4403110/blog/4496778