目錄python
針對YOLO官方提供的c語言版的darknet進行了修改,添加了一些函數,進行可視化處理。數組
建議使用visual studio code進行代碼的跟蹤和調試。網絡
可視化內容是針對一下命令,對一張圖片進行可視化:函數
./darknet detector test cfg/voc.data data/yolov3-voc.cfg backup/yolov3-voc_40000.cfg
} else if (0 == strcmp(argv[1], "detector")){ run_detector(argc, argv);
if(0==strcmp(argv[2], "test")) test_detector(datacfg, cfg, weights, filename, thresh, hier_thresh, outfile, fullscreen); else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear); else if(0==strcmp(argv[2], "valid")) validate_detector(datacfg, cfg, weights, outfile); else if(0==strcmp(argv[2], "valid2")) validate_detector_flip(datacfg, cfg, weights, outfile); else if(0==strcmp(argv[2], "recall")) validate_detector_recall(datacfg, cfg, weights); else if(0==strcmp(argv[2], "demo")) {
while(1){ if(filename){ strncpy(input, filename, 256); image im = load_image_color(input,0,0); image sized = letterbox_image(im, net->w, net->h); layer l = net->layers[net->n-1]; float *X = sized.data; time=what_time_is_it_now(); network_predict(net, X); printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time); int nboxes = 0; detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
float *network_predict(network *net, float *input) { network orig = *net; net->input = input; net->truth = 0; net->train = 0; net->delta = 0; forward_network(net); float *out = net->output; *net = orig; return out; }
void forward_network(network *netp) { #ifdef GPU if(netp->gpu_index >= 0){ forward_network_gpu(netp); return; } #endif network net = *netp; printf("haha, net layer number: %d\n",net.n); int i; for(i = 0; i < net.n; ++i){ //image imi = get_network_image(netp); //save_image(imi,"thiisisatest"); net.index = i; layer l = net.layers[i]; if(l.delta){ fill_cpu(l.outputs * l.batch, 0, l.delta, 1); } l.forward(l, net); net.input = l.output; if(l.truth) { net.truth = l.output; } } calc_network_cost(netp); }
void forward_network_gpu(network *netp) { network net = *netp; cuda_set_device(net.gpu_index); cuda_push_array(net.input_gpu, net.input, net.inputs*net.batch); if(net.truth){ cuda_push_array(net.truth_gpu, net.truth, net.truths*net.batch); } int i; for(i = 0; i < net.n; ++i){ net.index = i; layer l = net.layers[i]; if(l.delta_gpu){ fill_gpu(l.outputs * l.batch, 0, l.delta_gpu, 1); } l.forward_gpu(l, net); net.input_gpu = l.output_gpu; net.input = l.output; if(l.truth) { net.truth_gpu = l.output_gpu; net.truth = l.output; } //這個函數是新加的,用來獲得圖片保存圖片 image tmp = get_network_cow_image_layer(&net,i); } pull_network_output(netp); calc_network_cost(netp); }
image get_network_cow_image_layer(network *net, int i);
具體內容以下:ui
image get_network_cow_image_layer(network *net, int i) { layer l = net->layers[i]; #ifdef GPU cuda_pull_array(l.output_gpu, l.output, l.outputs); #endif printf("w:%d,h:%d,c:%d\n",l.out_w,l.out_h,l.out_c); if (l.out_w && l.out_h && l.out_c){ return float_to_cow_image(l.out_w,l.out_h,l.out_c,l.output,i); } image def = {0}; return def; }
image get_network_cow_image_layer(network *net, int i);
該函數具體內容以下(參考get_network_image_layer進行修改,添加i是爲了識別這是第幾層的可視化,用於保存文件):spa
/***************************************************** *func: 主要是爲了將output結果可以映射到0-255區間(初始化,使用sigmoid函數進行歸一化,),便於進行可視化操做。 將全部維度合成到一個維度,而後取平均,×255,便於查看 *****************************************************/ image float_to_cow_image(int w, int h, int c, float *data,int ai) { char tp[1000]; //保存文件到特定文件夾(feature_txt)中並根據ai大小命名 sprintf(tp,"/home/learner/darknet/feature_txt/out_%d.txt",ai); FILE * stream = fopen(tp,"w+"); //建立一個1維的空圖片 image out = make_empty_image(w,h,1); int i, j; //設計一個數組保存該圖片內容 float * tempData = calloc(w*h,sizeof(float)); //初始化 for(i = 0 ; i < w*h ; i++) { tempData[i] = 0; } //歸一化,sigmoid for(i = 0 ; i < w*h*c ; i++) { data[i] = 1.0/(1+exp(-1*data[i])); } //合併通道 for(i = 0 ; i < w*h ; i++) { for(j = 0 ; j < c ; j++) { tempData[i] += data[i+j*w*h]; } } //保存到文件 for(i = 0 ; i < w*h; i++) { tempData[i] /= c; tempData[i] *= 255; fprintf(stream," %f",tempData[i]); if((i+1)%w==0) fprintf(stream,"\n"); } //關閉文件流 fclose(stream); out.data = tempData; return out; }
從新make,運行命令,會在指定目錄下獲得txt文件,以後的操做就是須要將txt文件可視化爲圖片。設計
使用python讀取圖片有一個好處,就是能夠將灰度圖轉化爲熱力圖,這樣更容易觀察,不然會認爲生成了一系列噪音點。調試
具體代碼以下:(須要matplotlib,PIL, numpy庫)code
#!/home/learner/miniconda3/bin/python # -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. """ import os import matplotlib.pyplot as plt import numpy as np from PIL import Image def process(filepath,outpath): for fileName in os.listdir(filepath): print(fileName) print(filepath+"/"+fileName) a=np.loadtxt(filepath+"/"+fileName) im = Image.fromarray(np.uint8(a)) #tmp_img = plt.imshow(im) #tmp_img.set_cmap('hsv') #plt.show() print(im.size) #im.set_cmap('hot') #plt.figure(figsize=(15,15)) plt.title(fileName) plt.imshow(im),plt.axis('off') im.save(outpath+"/"+fileName[:-4]+".jpg") #plt.savefig(outpath+"/"+fileName[:-4]+".jpg",bbox_inches="tight",transparent=True,pad_inches=0) if __name__ == "__main__": outpath = "/home/learner/darknet/feature_pic" filepath="/home/learner/darknet/feature_txt" process(filepath,outpath)