YOLOv4(darknet版)後處理:顯示置信度、保存檢測框的內容到本地

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

相關文章
相關標籤/搜索