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; }
    作者:华王
博客:https://www.cnblogs.com/huahuawang/
                    
                
                
            
        
浙公网安备 33010602011771号