目錄
以前寫了一篇使用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的方法切片並保存,有更好的方法歡迎留言。