1 C++算法实例

 

1 点在多边形内部的算法

需求:AI画多边形框的的问题(射线法)

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;
#define EPSILON 0.000001  //叉积误差范围
#define FLT_Min 0

struct Point{ // 创建点坐标
    float x;
    float y;
    
    Point(){
        x=0.0;
        y=0.0;
        }
    Point(float dx,float dy){
            x=dx;
            y=dy;
        }
    void Set_point(float dx ,float dy){
        x = dx;
        y = dy;
    }
};

class Graph
{
    //#############  todo1  //可以加一个构造函数
   public:
    Graph(){}    
    
      float Max_x;   // 最大横坐标
      float Min_x;  // 最小横坐标
      float Max_y;   // 最大纵坐标
      float Min_y;   // 最小纵坐标
      int point_number; // 顶点个数
      vector<Point> POL;  //存放点坐标
      
    //  float poly_X[]; //顶点X轴坐标
    //  float poly_Y[];  //顶点Y轴坐标
       
};


//判断点在线段上(叉积)
bool IsPointOnLine(float px0, float py0, float px1, float py1, float px2, float py2)
{
    bool flag = false;
    float d1 = (px1 - px0) * (py2 - py0) - (px2 - px0) * (py1 - py0);
    if ((abs(d1) < EPSILON) && ((px0 - px1) * (px0 - px2) <= 0) && ((py0 - py1) * (py0 - py2) <= 0))
    {
        flag = true;
    }
    return flag;
}


//判断两线段相交(叉积)
bool IsIntersect(float px1, float py1, float px2, float py2, float px3, float py3, float px4, float py4)
{
    bool flag = false;
    float d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
    if (d != 0)
    {
        float r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3)) / d;
        float s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1)) / d;
        if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1))
        {
            flag = true;
        }
    }
    return flag;
}

//判断点在多边形内
bool Point_In_Polygon_2D(float x, float y, const vector<Point> &POL)
{    
    bool isInside = false;
    int count = 0;
    
    //定义point,与线段端点
    float px = x;
    float py = y;
    float linePoint1x = x;
    float linePoint1y = y;
    float linePoint2x = FLT_Min -10;            //取最小的X值还小的值作为射线的终点
    float linePoint2y = y;

    //遍历每一条边
    for (int i = 0; i < POL.size() - 1; i++)
    {    
        float cx1 = POL[i].x;
        float cy1 = POL[i].y;
        float cx2 = POL[i + 1].x;
        float cy2 = POL[i + 1].y;
                
        if (IsPointOnLine(px, py, cx1, cy1, cx2, cy2))
        {
            return true;
        }

        if (fabs(cy2 - cy1) < EPSILON)   //平行则不相交
        {
            continue;
        }

        if (IsPointOnLine(cx1, cy1, linePoint1x, linePoint1y, linePoint2x, linePoint2y))
        {
            if (cy1 > cy2)            //只保证上端点+1
            {
                count++;
            }
        }
        else if (IsPointOnLine(cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y))
        {
            if (cy2 > cy1)            //只保证上端点+1
            {
                count++;
            }
        }
        else if (IsIntersect(cx1, cy1, cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y))   //已经排除平行的情况
        {
            count++;
        }
    }
    
    if (count % 2 == 1)
    {
        isInside = true;
    }

    return isInside;
}


//获取图像位置关系(graph_2默认为识别框)
 void get_graph_position(Graph graph,float x,float y){
     
        
        //1 define中心点 ,与多边形判断
        float center_x =x;
        float center_y =y;
        const vector<Point> POL =graph.POL;
        
        //2 进行点的位置判断
        if (Point_In_Polygon_2D(center_x, center_y, POL))
        {
            cout << center_x<<","<< center_y<<"点在多边形内" << endl;
        }
        else
        {
            cout << center_x<<","<< center_y<<"点在多边形外" << endl;
        }
        
        cout<<" ————————————————-————2———————————————————————\n"<<endl;
}


//预处理:快速排除相离的情况,提高效率
 bool fastExclude(Graph graph,float x,float y){
    
    float graph_MaxX = graph.Max_x;
    float graph_MaxY = graph.Max_y;
    float graph_MinX = graph.Min_x;
    float graph_MinY = graph.Min_y;
    
    float center_x =x;
    float center_y =y;
    
    printf("######### 1中心点(%f,%f)的预判断 #####",center_x,center_y);
    
    if (center_x>=graph_MaxX){
        cout<<"落在第一区域"<<endl; return false; 
        }
    else if (center_y<=graph_MinY) {
        cout<<"落在在第二区域"<<endl;return false;
        }
    else if (center_x<=graph_MinX) {
        cout<<"落在第三区域"<<endl;return false;
        }
    else if (center_y>=graph_MaxY) {
        cout<<"落在第四区域"<<endl;return false;
        }
    else {
        cout<<"在多边形的外包矩形内--judge_next"<<endl;return true;
    }
    cout << "############Pre_handle over !!#################"<<endl;
        
 }
 
int main()
//判断多边形位置关系
{
     // 1 init
     
     while(1)
     {
         
    Graph graph;
    
    float center_x;
    float center_y;
    cout<<"输入x: ";
    cin>>center_x;
    cout<< "输入y: ";
    cin>>center_y;
    
    
    //312.5:165:962.5:122.5:1275:355:1145:832.5:365:965:105:642.5:312.5:165 (// 不规则框)

    //582.5:315:675:422.5:587.5:620:392.5:627.5:367.5:497.5:477.5:427.5:582.5:315(inner点)
    
    graph.Max_x = 1275.0;
    graph.Min_x = 105.0;
    graph.Max_y = 965.0;
    graph.Min_y = 122.0;
    graph.POL.push_back(Point(312.0,165.0));
    graph.POL.push_back(Point(965.0,122.0));
    graph.POL.push_back(Point(1275.0,355.0));
    graph.POL.push_back(Point(1145.0,832.0));
    graph.POL.push_back(Point(365.0,965.0));
    graph.POL.push_back(Point(105.0,642.0));
    graph.POL.push_back(Point(312.0,165.0));

    
    /*graph.Max_x = 1920.0;
    graph.Min_x = 0.0;
    graph.Max_y = 1080.0;
    graph.Min_y = 0.0;
    graph.POL.push_back(Point(0.0,0.0));
    graph.POL.push_back(Point(1920.0,0.0));
    graph.POL.push_back(Point(1920.0,1080.0));
    graph.POL.push_back(Point(0.0,1080.0));
    graph.POL.push_back(Point(0.0,0.0));
   */
   
   /*
    graph.POL.push_back(Point(268.28, 784.75));
    graph.POL.push_back(Point(153.98, 600.60));
    graph.POL.push_back(Point(274.63, 336.02));
    graph.POL.push_back(Point(623.88, 401.64));
    graph.POL.push_back(Point(676.80, 634.47));
    graph.POL.push_back(Point(530.75, 822.85));
    graph.POL.push_back(Point(268.28, 784.75));
    */
    
    // 2 快速排除不相交的情况
    bool isfastExclude;
    isfastExclude=fastExclude(graph,center_x,center_y);
    if (!isfastExclude){cout<<" ——————————————————————1——————————————————————\n"<<endl; continue;}
    
    // 3进一步具体的位置关系
    printf("######### 2中心点精确判断 #########");
    get_graph_position(graph,center_x,center_y);
} 
}
点在多边形内部

 

2 计算IOU值

#include<iostream>
#include<algorithm>

using namespace std;

// 矩形框结构体
struct Rect {
    int x1, y1, x2, y2;  // 左上角坐标(x1,y1)和右下角坐标(x2,y2)
};

// 计算两个矩形框的交集
Rect get_intersection(const Rect &A, const Rect &B) {
    Rect inter;
    inter.x1 = max(A.x1, B.x1);
    inter.y1 = max(A.y1, B.y1);
    inter.x2 = min(A.x2, B.x2);
    inter.y2 = min(A.y2, B.y2);

    // 如果两个矩形框不相交,返回一个空矩形
    if (inter.x1 >= inter.x2 || inter.y1 >= inter.y2)
        inter.x1 = inter.y1 = inter.x2 = inter.y2 = 0;

    return inter;
}

// 计算两个矩形框的IOU值
float get_IOU(const Rect &A, const Rect &B) {
    Rect inter = get_intersection(A, B);
    cout << "inner: " << inter.x1<<inter.y1<<inter.x2<< inter.y2<< endl;
    float inter_area = (inter.x2 - inter.x1) * (inter.y2 - inter.y1);
    float A_area = (A.x2 - A.x1) * (A.y2 - A.y1);
    float B_area = (B.x2 - B.x1) * (B.y2 - B.y1);
    float iou = inter_area / (A_area + B_area - inter_area);
    return iou;
}

int main() {
    // 定义两个矩形框A和B
    Rect A = {0, 0, 3, 3};
    //Rect B = {1, 1, 2, 2};
    Rect B = {5, 5, 8, 8};

    // 计算两个矩形框的IOU并输出
    cout << "IOU: " << get_IOU(A, B) << endl;

    return 0;
}
IOU值计算

 

posted @ 2022-10-28 17:26  风hua  阅读(26)  评论(0)    收藏  举报