Yolo 比较好的两个版本:
官方版本:https://github.com/pjreddie/darknet
版本2 :https://github.com/AlexeyAB/darknet
版本2中,在window下效果也是非常好的,这个我也尝试过。
推荐使用版本2,速度比官方版本快,同时方便在后续处理。在官方版本中,读进的图片都是使用Image这个结构体来保存数据,而版本2使用的是OpenCV中IplImage,方便使用OpenCV自身带有的画框函数、文字标识以及对图片视频文件的保存。
Yolo的使用:
Yolo虽有有很多版本(yolov1,yolov2,yolov3和各个版本下的tiny版本),这些版本主要在网络设计上有不同,只会影响最终的识别速度和准确率。在使用yolo的时候,只关注输入和输出,以及可能对网咯的输出进行处理。
- 模型的训练:参照官网的介绍
https://pjreddie.com/darknet/yolo/
这里需要根据待识别数据的类别对检测的配置文件进行修改
需要修改的文件 :
darknet/cfg/coco.data (以coco为例,需修改训练和测试数据集路径)
darknet/cfg/coco.names(修改类别的名字)
Darknet/cfg/yolov3.cfg(修改输出的类别,输出的数据维度大小)
- yolo的输出:
Yolo对视频处理主要涉及到的源码文件为:
darknet/src/demo.c和darknet/src/image.c这两个文件
demo.c这个文件首先通过cap = cvCaptureFromFile(filename)(文件中290行),这个读取摄像获取到到的数据,然后通过两个线程对图片中物体进行识别,
void *detect_in_thread(void *ptr) |
|
| { |
| running = 1; |
| float nms = .4; |
|
|
| layer l = net->layers[net->n-1]; |
| float *X = buff_letter[(buff_index+2)%3].data; |
| network_predict(net, X); |
|
|
| /* |
| if(l.type == DETECTION){ |
| get_detection_boxes(l, 1, 1, demo_thresh, probs, boxes, 0); |
| } else */ |
| remember_network(net); |
| detection *dets = 0; |
| int nboxes = 0; |
| dets = avg_predictions(net, &nboxes); |
|
|
|
|
| /* |
| int i,j; |
| box zero = {0}; |
| int classes = l.classes; |
| for(i = 0; i < demo_detections; ++i){ |
| avg[i].objectness = 0; |
| avg[i].bbox = zero; |
| memset(avg[i].prob, 0, classes*sizeof(float)); |
| for(j = 0; j < demo_frame; ++j){ |
| axpy_cpu(classes, 1./demo_frame, dets[j][i].prob, 1, avg[i].prob, 1); |
| avg[i].objectness += dets[j][i].objectness * 1./demo_frame; |
| avg[i].bbox.x += dets[j][i].bbox.x * 1./demo_frame; |
| avg[i].bbox.y += dets[j][i].bbox.y * 1./demo_frame; |
| avg[i].bbox.w += dets[j][i].bbox.w * 1./demo_frame; |
| avg[i].bbox.h += dets[j][i].bbox.h * 1./demo_frame; |
| } |
| //copy_cpu(classes, dets[0][i].prob, 1, avg[i].prob, 1); |
| //avg[i].objectness = dets[0][i].objectness; |
| } |
| */ |
|
|
| if (nms > 0) do_nms_obj(dets, nboxes, l.classes, nms); |
|
|
| printf("\033[2J"); |
| printf("\033[1;1H"); |
| printf("\nFPS:%.1f\n",fps);//1秒处理多少张图片 |
| printf("Objects:\n\n"); |
| image display = buff[(buff_index+2) % 3]; |
| draw_detections(display, dets, nboxes, demo_thresh, demo_names, demo_alphabet, demo_classes); |
| free_detections(dets, nboxes); |
|
|
| demo_index = (demo_index + 1)%demo_frame; |
| running = 0; |
| return 0; |
| } |
这部分中最重要的就是draw_detections(display, dets, nboxes, demo_thresh, demo_names, demo_alphabet, demo_classes);这个函数在image.c中,labelstr代表的检测到物体的标签;
int right = (b.x+b.w/2.)*im.w; |
int top = (b.y-b.h/2.)*im.h; |
int bot = (b.y+b.h/2.)*im.h; |
int left = (b.x-b.w/2.)*im.w; |
Left,right,top,bot代表检测到物体的坐标
根据自己的需求,自定义draw_detections这个函数,实现一些其他的检测任务。