/******************实现功能:判断平面任一点是否在指定多边形内********************/
1 #include <string> 2 #include <vector> 3 #include <math.h> 4 #include <iostream> 5 #include <fstream> 6 #include <sstream> 7 8 using namespace std; 9 10 typedef struct { int x, y; } Point; 11 12 //算法说明 file:///D:/ddb/相机标定/Point_In_Polygon.pdf 13 // a Point is defined by its coordinates {int x, y;} 14 //=================================================================== 15 16 // isLeft(): tests if a point is Left|On|Right of an infinite line. 17 // Input: three points P0, P1, and P2 18 // Return: >0 for P2 left of the line through P0 and P1 19 // =0 for P2 on the line 20 // <0 for P2 right of the line 21 // See: Algorithm 1 "Area of Triangles and Polygons" 22 23 inline int 24 isLeft(Point P0, Point P1, Point P2) 25 { 26 return ((P1.x - P0.x) * (P2.y - P0.y) 27 - (P2.x - P0.x) * (P1.y - P0.y)); 28 } 29 30 //================================================================== 31 // cn_PnPoly(): crossing number test for a point in a polygon 32 // Input: P = a point, 33 // V[] = vertex points of a polygon V[n+1] with V[n]=V[0] 34 // Return: 0 = outside, 1 = inside 35 // This code is patterned after [Franklin, 2000] 36 int 37 cn_PnPoly(Point P, Point* V, int n) 38 { 39 int cn = 0; // the crossing number counter 40 41 // loop through all edges of the polygon 42 for (int i = 0; i < n; i++) 43 { 44 // edge from V[i] to V[i+1] 45 if (((V[i].y <= P.y) && (V[i + 1].y > P.y))||((V[i].y > P.y) && (V[i + 1].y <= P.y))) // an upward crossing 46 { 47 // a downward crossing 48 // compute the actual edge-ray intersect x-coordinate 49 float vt = (float)(P.y - V[i].y) / (V[i + 1].y - V[i].y); 50 if (P.x < V[i].x + vt * (V[i + 1].x - V[i].x)) // P.x < intersect 51 ++cn; // a valid crossing of y=P.y right of P.x 52 } 53 } 54 return (cn & 1); // 0 if even (out), and 1 if odd (in) 55 } 56 57 // wn_PnPoly(): winding number test for a point in a polygon 58 // Input: P = a point, 59 // V[] = vertex points of a polygon V[n+1] with V[n]=V[0] 60 // Return: wn = the winding number (=0 only when P is outside) 61 int 62 wn_PnPoly(Point P, Point* V, int n) 63 { 64 int wn = 0; // the winding number counter 65 // loop through all edges of the polygon 66 for (int i = 0; i<n; i++) 67 { 68 // edge from V[i] to V[i+1] 69 if (V[i].y <= P.y) 70 { 71 // start y <= P.y 72 if (V[i + 1].y > P.y) // an upward crossing 73 if (isLeft(V[i], V[i + 1], P) > 0) // P left of edge 74 ++wn; // have a valid up intersect 75 } 76 else 77 { // start y > P.y (no test needed) 78 if (V[i + 1].y <= P.y) // a downward crossing 79 if (isLeft(V[i], V[i + 1], P) < 0) // P right of edge 80 --wn; // have a valid down intersect 81 } 82 } 83 return wn; 84 } 85 86 87 int 88 wn_PnPoly_ddb(Point& P, const std::vector<Point>& V) // std::vector<Point>& V = vertex points of a polygon V[n + 1] with V[n] = V[0] , 注意多一个点首尾相同 89 { 90 int wn = 0; // the winding number counter 91 int n = V.size() - 1; // loop through all edges of the polygon 92 for (int i = 0; i<n; i++) 93 { 94 // edge from V[i] to V[i+1] 95 if (V[i].y <= P.y) 96 { 97 // start y <= P.y 98 if (V[i + 1].y > P.y) // an upward crossing 99 if (isLeft(V[i], V[i + 1], P) > 0) // P left of edge 100 ++wn; // have a valid up intersect 101 } 102 else 103 { // start y > P.y (no test needed) 104 if (V[i + 1].y <= P.y) // a downward crossing 105 if (isLeft(V[i], V[i + 1], P) < 0) // P right of edge 106 --wn; // have a valid down intersect 107 } 108 } 109 return wn; 110 } 111 112 void 113 readImageROIpolygen(const std::string& path, std::vector<Point>& pointVec, int i) 114 { 115 char name[60]; 116 string filename; 117 Point p2d; 118 119 int length = sprintf(name, "%d%s", i + 1, "_ROI.txt"); 120 filename = path + "/" + name; 121 ifstream infile(filename); 122 123 string Fline; 124 if (infile) // 有该文件 125 { 126 while (getline(infile, Fline)) // Fline中不包括每行的换行符 127 { 128 //cout << Fline << endl; 129 string buf; 130 stringstream ss(Fline); // 字符流ss 131 vector<string> tokens; // vector 132 133 // 按照逗号分隔 134 while (getline(ss, buf, ',')) 135 { 136 tokens.push_back(buf); 137 } 138 139 ////stringstream 按空格分开字符输入 140 //while (ss >> buf) 141 //{ 142 // tokens.push_back(buf); 143 //} 144 145 if (tokens.size()<1) 146 { 147 continue; 148 } 149 else if (tokens.size() == 2) 150 { 151 int j = 0; 152 p2d.x = atof(tokens[j].c_str()); //根据字段顺序做修改 对应图像 u v 153 j++; 154 p2d.y = atof(tokens[j].c_str()); 155 pointVec.push_back(p2d); 156 } 157 } 158 pointVec.push_back(pointVec[0]); 159 //std::cout << i << endl; 160 } 161 else // 没有该文件 162 { 163 cout << "error:: no such file" << endl; 164 } 165 infile.close(); 166 167 } 168 169 /**************** Test ****************/ 170 void 171 main() 172 { 173 Point detectPoint; 174 detectPoint.x = 2653; //1363, 1260 //2896,2276 //2653,390 175 detectPoint.y = 390; 176 std::string path="矫正后图像"; 177 178 std::vector<Point> pointVec; 179 readImageROIpolygen(path, pointVec,0); 180 if (pointVec.size()==0) 181 { 182 cout << "no ROI!!!" << endl; 183 return; 184 } 185 186 if (wn_PnPoly_ddb(detectPoint, pointVec) == 0) 187 { 188 cout << "detectPoint outside ImageROIpolygen!!!!" << endl; 189 } 190 else 191 { 192 cout << "detectPoint in ImageROIpolygen!!!!" << endl; 193 } 194 195 system("pause"); 196 }