c++ iou学习笔记

以下内容转自:

图像处理之IOU, NMS原理及C++实现 - 灰信网(软件开发博客聚合)

1. IOU

交并比(Intersection-over-Union,IoU),目标检测中使用的一个概念,是产生的候选框(candidate bound)与原标记框(ground truth bound)的交叠率,即它们的交集与并集的比值。最理想情况是完全重叠,即比值为1。

c++ iou学习笔记_第1张图片


计算公式:


C++代码:

opencv:


float bbOverlap(const cv::Rect_& box1,const cv::Rect_& box2)
{
  if (box1.x > box2.x+box2.width) { return 0.0; }
  if (box1.y > box2.y+box2.height) { return 0.0; }
  if (box1.x+box1.width < box2.x) { return 0.0; }
  if (box1.y+box1.height < box2.y) { return 0.0; }
  float colInt =  min(box1.x+box1.width,box2.x+box2.width) - max(box1.x, box2.x);
  float rowInt =  min(box1.y+box1.height,box2.y+box2.height) - max(box1.y,box2.y);
  float intersection = colInt * rowInt;
  float area1 = box1.width*box1.height;
  float area2 = box2.width*box2.height;
  return intersection / (area1 + area2 - intersection);
}

自定义结构:

struct bbox
{
	int m_left;
	int m_top;
	int m_width;
	int m_height;
 
	bbox() {}
	bbox(int left, int top, int width, int height) 
	{
		m_left = left;
		m_top = top;
		m_width = width;
		m_height = height;
	}
};

float IOU_compute(const bbox b1, const bbox b2)
{
    w = max(min((b1.m_left + b1.m_width), (b2.m_left + b2.m_width)) - max(b1.m_left, b2.m_left), 0);
    h = max(min((b1.m_top + b1.m_height), (b2.m_top + b2.m_height)) - max(b1.m_top, b2.m_top), 0);

    return w*h / (b1.m_width*b1.m_height + b2.m_width*b2.m_height - w*h);
}

3维目标检测iou:

一、三维目标表示
世界坐标系下的三维目标有9个自由度,分别为三个自由度的平移量(中心点坐标){x,y,z},三自由度的旋转{roll, pitch, yaw},三自由度的尺寸{length,width,height}。通常假设物体都是水平放置,所以roll = 0,pitch = 0;因此一个立方体可以表示为{x,y,z,0,0,yaw,len,wid,hei}。其中len、wid、hei分别是立方体长宽高的一半。

原文链接:https://blog.csdn.net/qq_27399933/article/details/110876763

bool bInBox(const vector &vpBoxA, const cv::Point2f &p)
{
    std::vector corners = vpBoxA;
    for(int i = 0; i > linesA;
    for(int i = 0; i line{a,b,c,d};
        linesA.push_back(line);
    }

    for(int i=0; i l = linesA[i];
        double y = l[0] * p.x + l[1] * p.y +l[2];
        if(y * l[3] < 0)
            return false;
    }
    return true;
}

double InterSection_2D(const vector &vpBoxA, const vector &vpBoxB)
{
    double min_x, max_x, min_y, max_y;
    min_x = vpBoxA[0].x;
    max_x = vpBoxA[0].x;
    min_y = vpBoxA[0].y;
    max_y = vpBoxA[0].y;

    for(int i=1; i max_x)
            max_x = p.x;
        if(p.x < min_x)
            min_x = p.x;
        if(p.y > max_y)
            max_y = p.y;
        if(p.y < min_y)
            min_y = p.y;
    }
    for(int i=0; i max_x)
            max_x = p.x;
        if(p.x < min_x)
            min_x = p.x;
        if(p.y > max_y)
            max_y = p.y;
        if(p.y < min_y)
            min_y = p.y;
    }

    //将两个BBox的定点坐标最小值设置为0, 以防止有负数的产生
    vector vpBoxAA = vpBoxA;
    vector vpBoxBB = vpBoxB;

    //if(min_x < 0 && min_y < 0)
    for(int i=0; i  vground_points;
    std::vector  vlandmark_points;
    if(1)  //通过坐标旋转求取groundtruth立方体中 2D-Boundbox四个顶点的坐标
    {
        double cen_x = truth_poses(0,0);
        double cen_y = truth_poses(0,1);
        double len = truth_poses(0,6);
        double wid = truth_poses(0,7);
        double yaw = truth_poses(0,5);

        double x, y, xx, yy;
        x = cen_x - len;
        y = cen_y - wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p0(xx, yy);

        x = cen_x - len;
        y = cen_y + wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p1(xx, yy);

        x = cen_x + len;
        y = cen_y + wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p2(xx, yy);

        x = cen_x + len;
        y = cen_y - wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p3(xx, yy);

        vground_points = {p0, p1, p2, p3};
    }

    if(1)//通过坐标旋转求取landmark中 2D-Boundbox四个顶点的坐标
    {
        double cen_x = landmark_poses(0,0);
        double cen_y = landmark_poses(0,1);
        double len = landmark_poses(0,6);
        double wid = landmark_poses(0,7);
        double yaw = landmark_poses(0,5);

        double x, y, xx, yy;
        x = cen_x - len;
        y = cen_y - wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p0(xx, yy);

        x = cen_x - len;
        y = cen_y + wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p1(xx, yy);

        x = cen_x + len;
        y = cen_y + wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p2(xx, yy);

        x = cen_x + len;
        y = cen_y - wid;
        xx = (x - cen_x)*cos(yaw) - (y - cen_y)*sin(yaw) + cen_x;
        yy = (x - cen_x)*sin(yaw) + (y - cen_y)*cos(yaw) + cen_y;
        cv::Point2f p3(xx, yy);

        vlandmark_points = {p0, p1, p2, p3};
    }

    double iou_2d = InterSection_2D(vlandmark_points, vground_points);
    double iou_3d = 0;
    if (iou_2d > 0) {
        double tru_minz = truth_poses(0, 2) - truth_poses(0, 8);
        double tru_maxz = truth_poses(0, 2) + truth_poses(0, 8);

        double land_minz = landmark_poses(0, 2) - landmark_poses(0, 8);
        double land_maxz = landmark_poses(0, 2) + landmark_poses(0, 8);

        if (land_maxz < tru_maxz && land_maxz > tru_minz) {
            double height_iou = (land_maxz - tru_minz) / (tru_maxz - land_minz);
            iou_3d = iou_2d * height_iou;
        } else if (tru_maxz < land_maxz && tru_maxz > land_minz) {
            double height_iou = (tru_maxz - land_minz) / (land_maxz - tru_minz);
            iou_3d = iou_2d * height_iou;
        }
    }

    return iou_3d;
}


void main(int argc, char **argv)
{
    Eigen::MatrixXd truth_poses(1,9);
    truth_poses<<-0.4875, -0.798913, -1.125, 0, 0, -1.27409, 0.240477, 0.235315, 0.375;
    Eigen::MatrixXd landmark_poses(1,9);
    landmark_poses<<-0.506616, -0.796303, -1.20499, 0, 0, -0.345443, 0.22,  0.22, 0.4 ;
    double iou_3d = CuboidIoU_once(truth_poses, landmark_poses);
    cout<<"the iou of two cuboid is: "<

你可能感兴趣的:(c++基础,c++,学习,开发语言)