YOLO(YOU ONLY LOOK ONCE)
1.文章概要
用于目标检测(Object Detection)任务,可以一次性完成对象的检测和分类(Classfication)。检测速度能达到50帧(FPS)以上,mAP(mean average precision)在VOC达到70%以上。
上面解决的方法是相对于Faster RCNN这类检测算法来说的,同类的算法还有SSD(Single Shot MultiBox Detector),为何名称不缩写成SSMD。。。
2.基本思路
把图像分成SxS个格子,如果一个目标落在某个格子中,那么就由该格子负责预测这个目标,每个格子预测B个Box,每个预测有五个参数confidence,x,y,w,h。
x,y:目标中心坐标
w,h:目标长宽
除了检测目标的外接矩形外,还要检测目标类别。
预测值是一个SxSx(Bx5+C)的tensor(张量)。
在VOC数据集上S取7,B取2,C为20。
C为类别数量。
这里显然是存在一些缺陷的,最明显的例子就是当两个物体在一个格子内时就没法同时检测这两个目标了(毕竟后面的分类只能有一种)
![Upload Paste_Image.png failed. Please try again.]
训练图像大小问题?
被统一处理成416*416
关于图像大小处理的代码
3.代码实现
void fill_truth_region(char *path, float *truth, int classes, int num_boxes, int flip, float dx, float dy, float sx, float sy)
{
char labelpath[4096];
find_replace(path, "images", "labels", labelpath);
find_replace(labelpath, "JPEGImages", "labels", labelpath);
find_replace(labelpath, ".jpg", ".txt", labelpath);
find_replace(labelpath, ".png", ".txt", labelpath);
find_replace(labelpath, ".JPG", ".txt", labelpath);
find_replace(labelpath, ".JPEG", ".txt", labelpath);
int count = 0;
box_label *boxes = read_boxes(labelpath, &count);
randomize_boxes(boxes, count);
correct_boxes(boxes, count, dx, dy, sx, sy, flip);
float x,y,w,h;
int id;
int i;
for (i = 0; i < count; ++i) {
x = boxes[i].x;
y = boxes[i].y;
w = boxes[i].w;
h = boxes[i].h;
id = boxes[i].id;
if (w < .005 || h < .005) continue;
int col = (int)(x*num_boxes);
int row = (int)(y*num_boxes);
x = x*num_boxes - col;
y = y*num_boxes - row;
int index = (col+row*num_boxes)*(5+classes);
if (truth[index]) continue;
truth[index++] = 1;
if (id < classes) truth[index+id] = 1;
index += classes;
truth[index++] = x;
truth[index++] = y;
truth[index++] = w;
truth[index++] = h;
}
free(boxes);
}
上面这段代码用来构建目标值。从代码中可以明显开除如果某个格子内有多个目标是无法完成检测任务的。
nms算法
segmentation fault
如在把names改成中文,会出现segmentation fault。代码在图像上绘制文字,采用的是贴图的方式,也就是它只有10个数字和26个字母的图像,对于其它文字就不能绘制。