python画图绘制紫荆花_Darknet卷基层浅层特征可视化教程

Darknet浅层可视化教程

说明

针对YOLO官方提供的c语言版的darknet进行了修改,添加了一些函数,进行可视化处理。

建议使用visual studio code进行代码的跟踪和调试。

可视化内容是针对一下命令,对一张图片进行可视化:

./darknet detector test cfg/voc.data data/yolov3-voc.cfg backup/yolov3-voc_40000.weights

处理步骤

入口: darknet.c的main文件,找到以下声明:

} else if (0 == strcmp(argv[1], "detector")){

run_detector(argc, argv);

进入run_detector函数,在detector.c文件中找到以下代码:

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")) {

找到第二个参数“test”对应的函数: test_detector,进入该函数进行修改:

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);

很明显,network_predict函数就是用来让图片在网络中forward_gpu一下,然后得到结果,所以进入该函数:

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;

}

再继续找核心函数forward_network(net)

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);

}

由于本项目是在有GPU支持的情况下,所以会执行#ifdef和#endif之间的内容,继续找forward_network_gpu()函数。

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);

}

该函数在network.c文件中声明,需要在darknet.h中提前声明该函数:

image get_network_cow_image_layer(network *net, int i);

具体内容如下:

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;

}

可以发现,float_to_cow_image也是新加的函数,也需要加入到darknet.h中去:

image get_network_cow_image_layer(network *net, int i);

该函数具体内容如下(参考get_network_image_layer进行修改,添加i是为了识别这是第几层的可视化,用于保存文件):

/*****************************************************

*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可视化txt文件

使用python读取图片有一个好处,就是可以将灰度图转化为热力图,这样更容易观察,否则会认为生成了一系列噪音点。

具体代码如下:(需要matplotlib,PIL, numpy库)

#!/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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值