#include #include #include #include #include #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include #include #define M_PI 3.14 using namespace std; using namespace cv; //求得半径 double getdistance(Point2d circlecenter, Point2d circlepoint) { double distance = sqrt(pow(circlecenter.x - circlepoint.x,2)+ pow(circlecenter.y - circlepoint.y,2)); return distance; } //半径与圆弧的交点 void cospoint(Point2d pointLR, Point2d circlecenter, double r,vector&point) { Point2d point1, point2; if (pointLR.x - circlecenter.x == 0) //垂直 { point1.x = circlecenter.x; point1.y = circlecenter.y + r; point.push_back(point1); } else { float k = float(pointLR.y - circlecenter.y) / (pointLR.x - circlecenter.x); float b = circlecenter.y - k * circlecenter.x; float a = k * k + 1; float b1 = 2 * k * b - 2 * k * circlecenter.y - 2 * circlecenter.x; float c = circlecenter.x * circlecenter.x - r * r + (b - circlecenter.y) * (b - circlecenter.y); float dlta = b1 * b1 - 4 * a * c; if (dlta >= 0) { point1.x = (-b1 - sqrt(dlta)) / (2 * a); point2.x = (-b1 + sqrt(dlta)) / (2 * a); point1.y = k * point1.x + b; point2.y = k * point2.x + b; if (point1.y > point2.y) { point.push_back(point1); } else { point.push_back(point2); } } } } //得到扇形弧上的一系列点 void pointoncircle(Point2d pointL, Point2d pointR,Point2d circlecenter, double r, vector& point) { Point2d point1, point2; int len = pointR.x - pointL.x; for (int i = 0; i < len/8; i++) { if (abs(pointL.x + 8 * i - circlecenter.x) <= 5) { point1.x = circlecenter.x; point1.y = circlecenter.y + r; point.push_back(point1); } else { float k = float(pointL.y - circlecenter.y) / (pointL.x + 8*i - circlecenter.x); float b = circlecenter.y - k * circlecenter.x; float a = k * k + 1; float b1 = 2 * k * b - 2 * k * circlecenter.y - 2 * circlecenter.x; float c = circlecenter.x * circlecenter.x - r * r + (b - circlecenter.y) * (b - circlecenter.y); float dlta = b1 * b1 - 4 * a * c; if (dlta >= 0) { double point1x = (-b1 - sqrt(dlta)) / (2 * a); double point2x = (-b1 + sqrt(dlta)) / (2 * a); double point1y = k * point1x + b; double point2y = k * point2x + b; if (point1y > point2y) { point.push_back(Point2d(point1x, point1y)); } else { point.push_back(Point2d(point2x, point2y)); } } } } } /* get angle ACB, point C is the center point A(x1,y1) B(x2,y2) C(x3,y3) */ //求得角度 double get_angle_with_points(double x1, double y1, double x2, double y2, double x3, double y3) { double theta = atan2(x1 - x3, y1 - y3) - atan2(x2 - x3, y2 - y3); if (theta > M_PI) theta -= 2 * M_PI; if (theta < -M_PI) theta += 2 * M_PI; theta = abs(theta * 180.0 / M_PI); if (y2 <= y3) { theta = 360.0 - theta; } return theta; } //两直线交点(扇形顶点) void getCenterPoint(vectorpointLU, vectorpointRU, Point2d& circlecenter) { 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)) / ((pointRU[0].x - pointRU[1].x) * (pointLU[0].y - pointLU[1].y) - (pointLU[0].x - pointLU[1].x) * (pointRU[0].y - pointRU[1].y)); 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)) / ((pointRU[0].y - pointRU[1].y) * (pointLU[0].x - pointLU[1].x) - (pointLU[0].y - pointLU[1].y) * (pointRU[0].x - pointRU[1].x)); circlecenter.x = x; circlecenter.y = y; } //读取json文件中的信息,获得需要的点坐标 void readFileJson(string filePath, vector&pointLU, vector& pointRU, Point2d& circlepoint, string& typelabel) { Json::Reader reader; Json::Value root; //读取文件中的数据 fstream in; in.open(filePath, ios::in || ios::binary); if (!in.is_open()) { cout << "Error opening file\n"; return; } if (reader.parse(in, root)) { //读取数组信息 unsigned int m = 0; unsigned int n = 1; const Json::Value arrValue = root["shapes"]; typelabel = arrValue[m]["label"].asString(); if (typelabel == "point1") { } else { const Json::Value sector = arrValue[m]["points"]; double sector1 = sector[m][m].asDouble(); double sector2 = sector[m][n].asDouble(); circlepoint.x = sector1; circlepoint.y = sector2; const Json::Value point1 = arrValue[m + 1]["points"]; double point1point1 = point1[m][m].asDouble(); double point1point2 = point1[m][n].asDouble(); Point2d pointLUu, pointLUd, pointRUu, pointRUd; pointLUu.x = point1point1; pointLUu.y = point1point2; pointLU.push_back(pointLUu); const Json::Value point2 = arrValue[m + 2]["points"]; double point2point1 = point2[m][m].asDouble(); double point2point2 = point2[m][n].asDouble(); pointLUd.x = point2point1; pointLUd.y = point2point2; pointLU.push_back(pointLUd); const Json::Value point3 = arrValue[m + 3]["points"]; double point3point1 = point3[m][m].asDouble(); double point3point2 = point3[m][n].asDouble(); pointRUu.x = point3point1; pointRUu.y = point3point2; pointRU.push_back(pointRUu); const Json::Value point4 = arrValue[m + 4]["points"]; double point4point1 = point4[m][m].asDouble(); double point4point2 = point4[m][n].asDouble(); pointRUd.x = point4point1; pointRUd.y = point4point2; pointRU.push_back(pointRUd); } } else { cout << "parse error\n" << endl; } in.close(); } //计算得到不同种类的扇形轮廓点 void GetLineAndPrint(string in_name) { ifstream fin(in_name); if (!fin) { cerr << "open file error" << endl; exit(-1); } vector pointLU; vector pointRU; Point2d circlecenter; Point2d circlepoint; string typelabel; vector allpoints; readFileJson(in_name, pointLU, pointRU,circlepoint, typelabel); //从文件中读取JSON if (typelabel == "point1") { } else { getCenterPoint(pointLU, pointRU, circlecenter); vector pointLD; vector pointRD; vector pointcircle; double R = getdistance(circlecenter, circlepoint); cospoint(pointLU[0], circlecenter, R, pointLD); cospoint(pointRU[0], circlecenter, R, pointRD); pointoncircle(pointLD[0], pointRD[0], circlecenter, R, pointcircle); if (typelabel == "sector1") { allpoints.push_back(1); allpoints.push_back(circlecenter.x); allpoints.push_back(circlecenter.y); allpoints.push_back(pointLD[0].x); allpoints.push_back(pointLD[0].y); for (int i = 1; i < pointcircle.size() - 1; i++) { allpoints.push_back(pointcircle[i].x); allpoints.push_back(pointcircle[i].y); } allpoints.push_back(pointRD[0].x); allpoints.push_back(pointRD[0].y); } else if (typelabel == "sectortrangle") { allpoints.push_back(2); allpoints.push_back(pointLU[0].x); allpoints.push_back(pointLU[0].y); allpoints.push_back(pointLD[0].x); allpoints.push_back(pointLD[0].y); for (int i = 1; i < pointcircle.size() - 1; i++) { allpoints.push_back(pointcircle[i].x); allpoints.push_back(pointcircle[i].y); } allpoints.push_back(pointRD[0].x); allpoints.push_back(pointRD[0].y); allpoints.push_back(pointRU[0].x); allpoints.push_back(pointRU[0].y); } else if (typelabel == "sector3") { allpoints.push_back(3); allpoints.push_back(circlecenter.x); allpoints.push_back(circlecenter.y); allpoints.push_back(pointLU[1].x); allpoints.push_back(pointLU[1].y); double pointld = double(sqrt(pow(R, 2) - pow(pointLU[1].x - circlecenter.x, 2)) + circlecenter.y); double pointrd = double(sqrt(pow(R, 2) - pow(pointRU[1].x - circlecenter.x, 2)) + circlecenter.y); allpoints.push_back(pointLU[1].x); allpoints.push_back(pointld); for (int i = 0; i < pointcircle.size(); i++) { if ((pointcircle[i].x > pointLU[1].x) && (pointcircle[i].x < pointRU[1].x)) { allpoints.push_back(pointcircle[i].x); allpoints.push_back(pointcircle[i].y); } } allpoints.push_back(pointRU[1].x); allpoints.push_back(pointrd); allpoints.push_back(pointRU[1].x); allpoints.push_back(pointRU[1].y); } else { vector pointcircleU; double RU = getdistance(circlecenter, pointLU[0]); pointoncircle(pointLU[0], pointRU[0], circlecenter, RU, pointcircleU); allpoints.push_back(4); allpoints.push_back(pointLU[0].x); allpoints.push_back(pointLU[0].y); allpoints.push_back(pointLD[0].x); allpoints.push_back(pointLD[0].y); for (int i = 1; i < pointcircle.size() - 1; i++) { allpoints.push_back(pointcircle[i].x); allpoints.push_back(pointcircle[i].y); } allpoints.push_back(pointRD[0].x); allpoints.push_back(pointRD[0].y); allpoints.push_back(pointRU[0].x); allpoints.push_back(pointRU[0].y); for (int i = pointcircleU.size() - 1; i > 1; i--) { allpoints.push_back(pointcircleU[i].x); allpoints.push_back(pointcircleU[i].y); } } } string newextension = ".txt"; size_t dot_pos = in_name.find_last_of("."); if (dot_pos == string::npos) { return; } in_name.replace(dot_pos, in_name.length() - dot_pos, newextension); ofstream outfile(in_name, ios::trunc); //ios::in可替换 //ios::app,表示打开文件后,在写入的文件不会覆盖原文件中的内容,也就是原来文件中的数据会得到保存。 //ios::trunc,文件里面的内容会清零 if (allpoints.size()==0) { outfile << "{\"ConclusionTitle\"" << ":\"noconcent\"" << "," << "\"Rois\"" << ":" << "null" << "}"; } else { string concent = "{\"Rois\""; string concent1 = "\"ConclusionTitle\""; string concent2 = "\"Points\""; outfile << concent << ":" << "[{" << concent1 << ":" << "\"" << allpoints[0] << "\"" << "," << concent2 << ":["; //写入数据 for (int i = 1; i < allpoints.size() / 2; i++) { outfile << "{" << "\"x\"" << ":" << allpoints[2 * i - 1] << "," << "\"y\"" << ":" << allpoints[2 * i] << "}" << ","; } outfile << "{" << "\"x\"" << ":" << allpoints[allpoints.size() - 2] << "," << "\"y\"" << ":" << allpoints[allpoints.size() - 1] << "}]}]}"; } outfile.close();//关闭文件,保存文件。 fin.close(); //删除json文件 string newextension1 = ".json"; size_t dot_pos1 = in_name.find_last_of("."); if (dot_pos1 == string::npos) { return; } in_name.replace(dot_pos1, in_name.length() - dot_pos1, newextension1); remove(in_name.c_str()); } int main() { struct _finddata_t fileinfo; string in_name; string in_path="F:\\labelme-3.11.2\\examples\\instance_segmentation\\sectortrangle"; string curr = in_path + "\\*.json"; long long handle; if ((handle = _findfirst(curr.c_str(), &fileinfo)) == -1L) { cout << "没有找到匹配文件!" << endl; return 0; } else { in_name = in_path + "\\" + fileinfo.name; GetLineAndPrint(in_name); while (_findnext(handle, &fileinfo) == 0) { in_name = in_path + "\\" + fileinfo.name; GetLineAndPrint(in_name); } _findclose(handle); } return 0; }