Sector.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. #include <iostream>
  2. #include <math.h>
  3. #include <cmath>
  4. #include <vector>
  5. #include <json.h>
  6. #include "opencv2/core/core.hpp"
  7. #include "opencv2/imgproc/imgproc.hpp"
  8. #include "opencv2/highgui/highgui.hpp"
  9. #include <fstream>
  10. #include <io.h>
  11. #define M_PI 3.14
  12. using namespace std;
  13. using namespace cv;
  14. //求得半径
  15. double getdistance(Point2d circlecenter, Point2d circlepoint)
  16. {
  17. double distance = sqrt(pow(circlecenter.x - circlepoint.x,2)+ pow(circlecenter.y - circlepoint.y,2));
  18. return distance;
  19. }
  20. //半径与圆弧的交点
  21. void cospoint(Point2d pointLR, Point2d circlecenter, double r,vector<cv::Point2d>&point)
  22. {
  23. Point2d point1, point2;
  24. if (pointLR.x - circlecenter.x == 0) //垂直
  25. {
  26. point1.x = circlecenter.x;
  27. point1.y = circlecenter.y + r;
  28. point.push_back(point1);
  29. }
  30. else
  31. {
  32. float k = float(pointLR.y - circlecenter.y) / (pointLR.x - circlecenter.x);
  33. float b = circlecenter.y - k * circlecenter.x;
  34. float a = k * k + 1;
  35. float b1 = 2 * k * b - 2 * k * circlecenter.y - 2 * circlecenter.x;
  36. float c = circlecenter.x * circlecenter.x - r * r + (b - circlecenter.y) * (b - circlecenter.y);
  37. float dlta = b1 * b1 - 4 * a * c;
  38. if (dlta >= 0)
  39. {
  40. point1.x = (-b1 - sqrt(dlta)) / (2 * a);
  41. point2.x = (-b1 + sqrt(dlta)) / (2 * a);
  42. point1.y = k * point1.x + b;
  43. point2.y = k * point2.x + b;
  44. if (point1.y > point2.y)
  45. {
  46. point.push_back(point1);
  47. }
  48. else
  49. {
  50. point.push_back(point2);
  51. }
  52. }
  53. }
  54. }
  55. //得到扇形弧上的一系列点
  56. void pointoncircle(Point2d pointL, Point2d pointR,Point2d circlecenter, double r, vector<cv::Point2d>& point)
  57. {
  58. Point2d point1, point2;
  59. int len = pointR.x - pointL.x;
  60. for (int i = 0; i < len/8; i++)
  61. {
  62. if (abs(pointL.x + 8 * i - circlecenter.x) <= 5)
  63. {
  64. point1.x = circlecenter.x;
  65. point1.y = circlecenter.y + r;
  66. point.push_back(point1);
  67. }
  68. else
  69. {
  70. float k = float(pointL.y - circlecenter.y) / (pointL.x + 8*i - circlecenter.x);
  71. float b = circlecenter.y - k * circlecenter.x;
  72. float a = k * k + 1;
  73. float b1 = 2 * k * b - 2 * k * circlecenter.y - 2 * circlecenter.x;
  74. float c = circlecenter.x * circlecenter.x - r * r + (b - circlecenter.y) * (b - circlecenter.y);
  75. float dlta = b1 * b1 - 4 * a * c;
  76. if (dlta >= 0)
  77. {
  78. double point1x = (-b1 - sqrt(dlta)) / (2 * a);
  79. double point2x = (-b1 + sqrt(dlta)) / (2 * a);
  80. double point1y = k * point1x + b;
  81. double point2y = k * point2x + b;
  82. if (point1y > point2y)
  83. {
  84. point.push_back(Point2d(point1x, point1y));
  85. }
  86. else
  87. {
  88. point.push_back(Point2d(point2x, point2y));
  89. }
  90. }
  91. }
  92. }
  93. }
  94. /*
  95. get angle ACB, point C is the center point
  96. A(x1,y1)
  97. B(x2,y2)
  98. C(x3,y3)
  99. */
  100. //求得角度
  101. double get_angle_with_points(double x1, double y1, double x2, double y2, double x3, double y3)
  102. {
  103. double theta = atan2(x1 - x3, y1 - y3) - atan2(x2 - x3, y2 - y3);
  104. if (theta > M_PI)
  105. theta -= 2 * M_PI;
  106. if (theta < -M_PI)
  107. theta += 2 * M_PI;
  108. theta = abs(theta * 180.0 / M_PI);
  109. if (y2 <= y3) {
  110. theta = 360.0 - theta;
  111. }
  112. return theta;
  113. }
  114. //两直线交点(扇形顶点)
  115. void getCenterPoint(vector<Point2d>pointLU, vector<Point2d>pointRU, Point2d& circlecenter)
  116. {
  117. double x = double((pointRU[0].x - pointRU[1].x) * (pointLU[1].x * pointLU[0].y - pointLU[0].x * pointLU[1].y) - (pointLU[0].x - pointLU[1].x) * (pointRU[1].x * pointRU[0].y - pointRU[0].x * pointRU[1].y)) /
  118. ((pointRU[0].x - pointRU[1].x) * (pointLU[0].y - pointLU[1].y) - (pointLU[0].x - pointLU[1].x) * (pointRU[0].y - pointRU[1].y));
  119. double y = double((pointRU[0].y - pointRU[1].y) * (pointLU[1].y * pointLU[0].x - pointLU[0].y * pointLU[1].x) - (pointLU[0].y - pointLU[1].y) * (pointRU[1].y * pointRU[0].x - pointRU[0].y * pointRU[1].x)) /
  120. ((pointRU[0].y - pointRU[1].y) * (pointLU[0].x - pointLU[1].x) - (pointLU[0].y - pointLU[1].y) * (pointRU[0].x - pointRU[1].x));
  121. circlecenter.x = x;
  122. circlecenter.y = y;
  123. }
  124. //读取json文件中的信息,获得需要的点坐标
  125. void readFileJson(string filePath, vector<Point2d>&pointLU, vector<Point2d>& pointRU, Point2d& circlepoint, string& typelabel)
  126. {
  127. Json::Reader reader;
  128. Json::Value root;
  129. //读取文件中的数据
  130. fstream in;
  131. in.open(filePath, ios::in || ios::binary);
  132. if (!in.is_open())
  133. {
  134. cout << "Error opening file\n";
  135. return;
  136. }
  137. if (reader.parse(in, root))
  138. {
  139. //读取数组信息
  140. unsigned int m = 0;
  141. unsigned int n = 1;
  142. const Json::Value arrValue = root["shapes"];
  143. typelabel = arrValue[m]["label"].asString();
  144. if (typelabel == "point1")
  145. {
  146. }
  147. else
  148. {
  149. const Json::Value sector = arrValue[m]["points"];
  150. double sector1 = sector[m][m].asDouble();
  151. double sector2 = sector[m][n].asDouble();
  152. circlepoint.x = sector1;
  153. circlepoint.y = sector2;
  154. const Json::Value point1 = arrValue[m + 1]["points"];
  155. double point1point1 = point1[m][m].asDouble();
  156. double point1point2 = point1[m][n].asDouble();
  157. Point2d pointLUu, pointLUd, pointRUu, pointRUd;
  158. pointLUu.x = point1point1;
  159. pointLUu.y = point1point2;
  160. pointLU.push_back(pointLUu);
  161. const Json::Value point2 = arrValue[m + 2]["points"];
  162. double point2point1 = point2[m][m].asDouble();
  163. double point2point2 = point2[m][n].asDouble();
  164. pointLUd.x = point2point1;
  165. pointLUd.y = point2point2;
  166. pointLU.push_back(pointLUd);
  167. const Json::Value point3 = arrValue[m + 3]["points"];
  168. double point3point1 = point3[m][m].asDouble();
  169. double point3point2 = point3[m][n].asDouble();
  170. pointRUu.x = point3point1;
  171. pointRUu.y = point3point2;
  172. pointRU.push_back(pointRUu);
  173. const Json::Value point4 = arrValue[m + 4]["points"];
  174. double point4point1 = point4[m][m].asDouble();
  175. double point4point2 = point4[m][n].asDouble();
  176. pointRUd.x = point4point1;
  177. pointRUd.y = point4point2;
  178. pointRU.push_back(pointRUd);
  179. }
  180. }
  181. else
  182. {
  183. cout << "parse error\n" << endl;
  184. }
  185. in.close();
  186. }
  187. //计算得到不同种类的扇形轮廓点
  188. void GetLineAndPrint(string in_name)
  189. {
  190. ifstream fin(in_name);
  191. if (!fin)
  192. {
  193. cerr << "open file error" << endl;
  194. exit(-1);
  195. }
  196. vector<cv::Point2d> pointLU;
  197. vector<cv::Point2d> pointRU;
  198. Point2d circlecenter;
  199. Point2d circlepoint;
  200. string typelabel;
  201. vector<int> allpoints;
  202. readFileJson(in_name, pointLU, pointRU,circlepoint, typelabel); //从文件中读取JSON
  203. if (typelabel == "point1")
  204. {
  205. }
  206. else
  207. {
  208. getCenterPoint(pointLU, pointRU, circlecenter);
  209. vector<cv::Point2d> pointLD;
  210. vector<cv::Point2d> pointRD;
  211. vector<cv::Point2d> pointcircle;
  212. double R = getdistance(circlecenter, circlepoint);
  213. cospoint(pointLU[0], circlecenter, R, pointLD);
  214. cospoint(pointRU[0], circlecenter, R, pointRD);
  215. pointoncircle(pointLD[0], pointRD[0], circlecenter, R, pointcircle);
  216. if (typelabel == "sector1")
  217. {
  218. allpoints.push_back(1);
  219. allpoints.push_back(circlecenter.x);
  220. allpoints.push_back(circlecenter.y);
  221. allpoints.push_back(pointLD[0].x);
  222. allpoints.push_back(pointLD[0].y);
  223. for (int i = 1; i < pointcircle.size() - 1; i++)
  224. {
  225. allpoints.push_back(pointcircle[i].x);
  226. allpoints.push_back(pointcircle[i].y);
  227. }
  228. allpoints.push_back(pointRD[0].x);
  229. allpoints.push_back(pointRD[0].y);
  230. }
  231. else if (typelabel == "sectortrangle")
  232. {
  233. allpoints.push_back(2);
  234. allpoints.push_back(pointLU[0].x);
  235. allpoints.push_back(pointLU[0].y);
  236. allpoints.push_back(pointLD[0].x);
  237. allpoints.push_back(pointLD[0].y);
  238. for (int i = 1; i < pointcircle.size() - 1; i++)
  239. {
  240. allpoints.push_back(pointcircle[i].x);
  241. allpoints.push_back(pointcircle[i].y);
  242. }
  243. allpoints.push_back(pointRD[0].x);
  244. allpoints.push_back(pointRD[0].y);
  245. allpoints.push_back(pointRU[0].x);
  246. allpoints.push_back(pointRU[0].y);
  247. }
  248. else if (typelabel == "sector3")
  249. {
  250. allpoints.push_back(3);
  251. allpoints.push_back(circlecenter.x);
  252. allpoints.push_back(circlecenter.y);
  253. allpoints.push_back(pointLU[1].x);
  254. allpoints.push_back(pointLU[1].y);
  255. double pointld = double(sqrt(pow(R, 2) - pow(pointLU[1].x - circlecenter.x, 2)) + circlecenter.y);
  256. double pointrd = double(sqrt(pow(R, 2) - pow(pointRU[1].x - circlecenter.x, 2)) + circlecenter.y);
  257. allpoints.push_back(pointLU[1].x);
  258. allpoints.push_back(pointld);
  259. for (int i = 0; i < pointcircle.size(); i++)
  260. {
  261. if ((pointcircle[i].x > pointLU[1].x) && (pointcircle[i].x < pointRU[1].x))
  262. {
  263. allpoints.push_back(pointcircle[i].x);
  264. allpoints.push_back(pointcircle[i].y);
  265. }
  266. }
  267. allpoints.push_back(pointRU[1].x);
  268. allpoints.push_back(pointrd);
  269. allpoints.push_back(pointRU[1].x);
  270. allpoints.push_back(pointRU[1].y);
  271. }
  272. else
  273. {
  274. vector<cv::Point2d> pointcircleU;
  275. double RU = getdistance(circlecenter, pointLU[0]);
  276. pointoncircle(pointLU[0], pointRU[0], circlecenter, RU, pointcircleU);
  277. allpoints.push_back(4);
  278. allpoints.push_back(pointLU[0].x);
  279. allpoints.push_back(pointLU[0].y);
  280. allpoints.push_back(pointLD[0].x);
  281. allpoints.push_back(pointLD[0].y);
  282. for (int i = 1; i < pointcircle.size() - 1; i++)
  283. {
  284. allpoints.push_back(pointcircle[i].x);
  285. allpoints.push_back(pointcircle[i].y);
  286. }
  287. allpoints.push_back(pointRD[0].x);
  288. allpoints.push_back(pointRD[0].y);
  289. allpoints.push_back(pointRU[0].x);
  290. allpoints.push_back(pointRU[0].y);
  291. for (int i = pointcircleU.size() - 1; i > 1; i--)
  292. {
  293. allpoints.push_back(pointcircleU[i].x);
  294. allpoints.push_back(pointcircleU[i].y);
  295. }
  296. }
  297. }
  298. string newextension = ".txt";
  299. size_t dot_pos = in_name.find_last_of(".");
  300. if (dot_pos == string::npos)
  301. {
  302. return;
  303. }
  304. in_name.replace(dot_pos, in_name.length() - dot_pos, newextension);
  305. ofstream outfile(in_name, ios::trunc);
  306. //ios::in可替换
  307. //ios::app,表示打开文件后,在写入的文件不会覆盖原文件中的内容,也就是原来文件中的数据会得到保存。
  308. //ios::trunc,文件里面的内容会清零
  309. if (allpoints.size()==0)
  310. {
  311. outfile << "{\"ConclusionTitle\"" << ":\"noconcent\"" << "," << "\"Rois\"" << ":" << "null" << "}";
  312. }
  313. else
  314. {
  315. string concent = "{\"Rois\"";
  316. string concent1 = "\"ConclusionTitle\"";
  317. string concent2 = "\"Points\"";
  318. outfile << concent << ":" << "[{" << concent1 << ":" << "\"" << allpoints[0] << "\"" << "," << concent2 << ":[";
  319. //写入数据
  320. for (int i = 1; i < allpoints.size() / 2; i++)
  321. {
  322. outfile << "{" << "\"x\"" << ":" << allpoints[2 * i - 1] << "," << "\"y\"" << ":" << allpoints[2 * i] << "}" << ",";
  323. }
  324. outfile << "{" << "\"x\"" << ":" << allpoints[allpoints.size() - 2] << "," << "\"y\"" << ":" << allpoints[allpoints.size() - 1] << "}]}]}";
  325. }
  326. outfile.close();//关闭文件,保存文件。
  327. fin.close();
  328. //删除json文件
  329. string newextension1 = ".json";
  330. size_t dot_pos1 = in_name.find_last_of(".");
  331. if (dot_pos1 == string::npos)
  332. {
  333. return;
  334. }
  335. in_name.replace(dot_pos1, in_name.length() - dot_pos1, newextension1);
  336. remove(in_name.c_str());
  337. }
  338. int main() {
  339. struct _finddata_t fileinfo;
  340. string in_name;
  341. string in_path="F:\\labelme-3.11.2\\examples\\instance_segmentation\\sectortrangle";
  342. string curr = in_path + "\\*.json";
  343. long long handle;
  344. if ((handle = _findfirst(curr.c_str(), &fileinfo)) == -1L)
  345. {
  346. cout << "没有找到匹配文件!" << endl;
  347. return 0;
  348. }
  349. else
  350. {
  351. in_name = in_path + "\\" + fileinfo.name;
  352. GetLineAndPrint(in_name);
  353. while (_findnext(handle, &fileinfo) == 0)
  354. {
  355. in_name = in_path + "\\" + fileinfo.name;
  356. GetLineAndPrint(in_name);
  357. }
  358. _findclose(handle);
  359. }
  360. return 0;
  361. }