在目标检测算法中,都会需要框出目标,其中的实现过程是一个关于候选框的回归,回归以后才能得到更加准确的框的坐标信息,和框的长宽。具体过程可以参考下面给出的源码,每一步都我给出了相应的注释,大家应该能看懂。
typedef struct FaceInfo {
float score;//置信度
int x[2];
int y[2];//框左下和右上的坐标点
float area;//框的面积
float regreCoord[4];//4个坐标的修正信息,返回的是框的比例
int landmark[10];//人脸的5个特征点
} FaceInfo;
refine(vector &bboxs, int height, int width, bool flag)
{
if (bboxs.empty())
return;
for (auto it = bboxs.begin(); it != bboxs.end(); it++)
{
float bw = it->x[1] - it->x[0] + 1;
float bh = it->y[1] - it->y[0] + 1;//得到候选框的长宽
float x0 = it->x[0] + it->regreCoord[0] * bw;
float y0 = it->y[0] + it->regreCoord[1] * bh;
float x1 = it->x[1] + it->regreCoord[2] * bw;
float y1 = it->y[1] + it->regreCoord[3] * bh;//修正为候选框的比例
if (flag)
{
float w = x1 - x0 + 1;
float h = y1 - y0 + 1;//防止宽高为0
float m = (h > w) ? h : w;
x0 = x0 + w * 0.5 - m * 0.5;
y0 = y0 + h * 0.5 - m * 0.5;//让x0或y0更小
x1 = x0 + m - 1;
y1 = y0 + m - 1;//让x1或y1更大
//效果相当于将候选框以两个点向外拉大了
}//这里的目的是让框尽可能的大一些,为了更好的将目标置于框中
it->x[0] = round(x0);
it->y[0] = round(y0);
it->x[1] = round(x1);
it->y[1] = round(y1);//取整赋值
if (it->x[0] < 0) it->x[0] = 0;
if (it->y[0] < 0) it->y[0] = 0;
if (it->x[1] > width) it->x[1] = width - 1;
if (it->y[1] > height) it->y[1] = height - 1;//限制坐标在图片里面
it->area = (it->x[1] - it->x[0]) * (it->y[1] - it->y[0]);
}