예제 #1
0
//
// Draw catenary curve between conductor attachment points
//	from the current tower to the previous tower.
//
void vtRoute::_DrawCat(FPoint3 pt0, FPoint3 pt1, double catenary,
					  int iNumSegs, vtMesh *pWireMesh)
{
	FPoint3 diff = pt1-pt0;
	FPoint3 ptNew;
	int i;
	double xz = sqrt(diff.z*diff.z+diff.x*diff.x);	// distance in the xz plane
	double y = diff.y;
	FPoint3 step = diff / (float) iNumSegs;

	// Calculate the parabolic constants.
	double parabolicConst = (xz / 2) - (y * (catenary / xz));

	FPoint3 ptCur(0,0,0);
	double dist=0;

	vtHeightField3d *pHeightField = m_pTheTerrain->GetHeightField();
	float ground;

	// Iterate along the xz-plane
	for (i = 0; i < iNumSegs-1; i++)
	{
		ptCur.x += step.x;
		ptCur.z += step.z;
		dist = sqrt(ptCur.x*ptCur.x + ptCur.z*ptCur.z);

		ptCur.y = (float) ((dist / (2*catenary)) * (dist - (2*parabolicConst)));

		ptNew = pt0 + ptCur;
		pHeightField->FindAltitudeAtPoint(ptNew, ground);
		ground += 0.5;
		if (ptNew.y < ground)
			ptNew.y = ground;

		pWireMesh->AddVertex(ptNew);
	}
}
//变角度线扫描法——改进后的线扫描法
void findCircleParameter::revisedScanLineMethod(Mat imgOrg, Point2i& center, int& radius, int threshold, int N)
{
	Mat src, gray;
	src = imgOrg.clone();
	cvtColor(src, gray, CV_BGR2GRAY);

	vector<Point> points;
	vector<double> distance;

	Size imgSize = src.size();

	int x, y;
	double theta = 0;

	for (int n = 0; n < 2 * N; n++, theta = PI*n / (2 * N))
	{
		//if (n == N||n==0) continue;
		int min1, min2;
		min1 = min2 = 255;
		int max1, max2;
		max1 = max2 = 0;
		int radius = 0;
		Point ptMax1(0, 0), ptMax2(0, 0);
		Point ptMin1(0, 0), ptMin2(0, 0);
		int flag = 0;

		double minVal, maxVal;

		if (0 == n)
		{
			for (int i = 0; i < imgSize.height; i++)
			{
				minMaxLoc(gray.row(i), &minVal, &maxVal, &ptMin1, &ptMax1);
				if ((maxVal - minVal)>threshold)
				{
					flag++;

					ptMax1.y = i;
					//cout << "horizontal top:" << endl;
					//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;
					points.push_back(ptMax1);
					goto top_label;
				}
			}
		top_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = imgSize.height - 1; i >= 0; i--)
			{
				minMaxLoc(gray.row(i), &minVal, &maxVal, &ptMin2, &ptMax2);
				if ((maxVal - minVal) > threshold)
				{
					flag++;

					ptMax2.y = i;
					//cout << "horizontal bottom:" << endl;
					//cout << "ptMax2=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;

					//src.row(i) = Scalar(0, 0, 255);
					//src.row(i + 1) = Scalar(0, 0, 255);

					points.push_back(ptMax2);
					goto bottom_label;
				}
			}
		bottom_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}
		}
		else if (0 < n&&n < N)
		{
			for (int i = 0; i < imgSize.width; i++)
			{
				for (int j = 0; j <= i; j++)
				{
					x = j;
					y = -tan(theta)*(x - i);

					Point ptCur(x, y);
					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}

					uchar I = gray.at<uchar>(ptCur);

					if (I > max1)
					{
						max1 = I;
						ptMax1 = ptCur;
					}
					if (I < min1)
					{
						min1 = I;
					}

					if (abs(max1 - min1) > threshold)
					{
						flag++;
						//cout << "jump outer1" << endl;
						//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;
						points.push_back(ptMax1);

						/*						Point start, end;
						for (int k = 0; k <= i; k++)
						{
						x = k;
						y = -tan(theta)*(x - i);
						if (k == 0)
						{
						start = Point(x, y);
						}
						else if (k == i)
						{
						end = Point(x, y);
						}


						}
						line(src, start, end, Scalar(0, 0, 255), 2);*/

						goto outer1;
					}
				}
			}
		outer1:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = imgSize.width - 1; i >= 0; i--)
			{
				for (int j = i; j < imgSize.width; j++)
				{
					x = j;
					y = imgSize.height - 1 - tan(theta)*(x - i);

					Point ptCur(x, y);

					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}
					uchar I = gray.at<uchar>(ptCur);

					if (I > max2)
					{
						max2 = I;
						ptMax2 = ptCur;
					}
					if (I < min2)
					{
						min2 = I;
					}

					if (abs(max2 - min2) > threshold)
					{
						flag++;
						//cout << "jump outer2" << endl;
						//cout << "ptMax2=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;
						points.push_back(ptMax2);

						//Point start, end;
						//for (int k = i; k < imgSize.width; k++)
						//{
						//	x = k;
						//	y = imgSize.height - 1 - tan(theta)*(x - i);
						//	if (k == i)
						//	{
						//		start = Point(x, y);
						//	}
						//	else if (k == imgSize.width-1)
						//	{
						//		end = Point(x, y);
						//	}


						//}
						//line(src, start, end, Scalar(0, 0, 255), 2);

						goto outer2;
					}
				}
			}
		outer2:
			;

#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}

		}
		else if (N == n)
		{
			for (int i = 0; i < imgSize.width; i++)
			{
				minMaxLoc(gray.col(i), &minVal, &maxVal, &ptMin1, &ptMax1);
				if ((maxVal - minVal)>threshold)
				{
					flag++;
					ptMax1.x = i;
					//cout << "vertical left:" << endl;
					//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;

					//src.col(i) = Scalar(0, 0, 255);
					//src.col(i - 1) = Scalar(0, 0, 255);
					points.push_back(ptMax1);
					goto left_label;
				}
			}
		left_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = gray.cols - 1; i >= 0; i--)
			{
				minMaxLoc(gray.col(i), &minVal, &maxVal, &ptMin2, &ptMax2);
				if ((maxVal - minVal) > threshold)
				{
					flag++;
					ptMax2.x = i;
					//cout << "vertical right:" << endl;
					//cout << "ptMax1=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;
					points.push_back(ptMax2);

					//src.col(i) = Scalar(0, 0, 255);
					//src.col(i + 1) = Scalar(0, 0, 255);

					goto right_label;
				}
			}

		right_label:

#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}

		}
		else if (N < n&&n < 2 * N)
		{
			for (int i = 0; i < imgSize.width; i++)
			{
				for (int j = 0; j <= i; j++)
				{
					x = j;
					y = imgSize.height - 1 - tan(theta)*(x - i);

					Point ptCur(x, y);
					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}
					uchar I = gray.at<uchar>(ptCur);

					if (I > max1)
					{
						max1 = I;
						ptMax1 = ptCur;
					}
					if (I < min1)
					{
						min1 = I;
					}

					if (abs(max1 - min1) > threshold)
					{
						flag++;
						//cout << "jump outer3" << endl;
						//cout << "ptMax1=(" << ptMax1.x << ", " << ptMax1.y << ")" << endl;
						points.push_back(ptMax1);

						//Point start, end;
						//for (int k = 0; k <= i; k++)
						//{
						//	x = k;
						//	y = imgSize.height - 1 - tan(theta)*(x - i);

						//	if (k == 0)
						//	{
						//		start = Point(x, y);
						//	}
						//	else if (k == i)
						//	{
						//		end = Point(x, y);
						//	}
						//}
						//line(src, start, end, Scalar(0, 0, 255), 2);

						goto outer3;
					}
				}
			}
		outer3:

#ifdef _SHOW_POINTS_
			circle(src, ptMax1, 5, Scalar(0, 255, 255), -1);
			imshow("src", src);
			waitKey();
#endif

			for (int i = imgSize.width - 1 / 2; i >= 0; i--)
			{
				for (int j = i; j < imgSize.width; j++)
				{
					x = j;
					y = -tan(theta)*(x - i);

					Point ptCur(x, y);
					if (!ptCur.inside(Rect(0, 0, imgSize.width, imgSize.height)))
					{
						continue;
					}
					uchar I = gray.at<uchar>(ptCur);

					if (I > max2)
					{
						max2 = I;
						ptMax2 = ptCur;
					}
					if (I < min2)
					{
						min2 = I;
					}

					if (abs(max2 - min2) > threshold)
					{
						flag++;
						//cout << "jump outer4" << endl;
						//cout << "ptMax2=(" << ptMax2.x << ", " << ptMax2.y << ")" << endl;
						points.push_back(ptMax2);

						/*			Point start, end;
						for (int k = i; k < imgSize.width; k++)
						{
						x = k;
						y = -tan(theta)*(x - i);
						if (k == i)
						{
						start = Point(x, y);
						}
						else if (k == imgSize.width - 1)
						{
						end = Point(x, y);
						}


						}
						line(src, start, end, Scalar(0, 0, 255), 2);*/

						goto outer4;
					}
				}
			}
		outer4:

			;
#ifdef _SHOW_POINTS_
			circle(src, ptMax2, 5, Scalar(0, 255, 255), -1);
			line(src, ptMax1, ptMax2, Scalar(192, 192, 0), 2);
			imshow("src", src);
			waitKey();
#endif
			if (flag == 2)
			{
				distance.push_back(sqrt(pow(ptMax1.x - ptMax2.x, 2) + pow(ptMax1.y - ptMax2.y, 2)));
			}
			else if (flag == 1)
			{
				points.pop_back();
			}

		}
		else
		{
			cout << "The value of n is error!" << endl;
			break;
		}
	}


	//vector<Point>::iterator itero = points.begin();
	//ofstream of("points.txt", ios::trunc | ios::out);
	//while (itero != points.end())
	//{
	//	of << (*itero).x << ", " << (*itero).y << endl;
	//	itero++;
	//}
	//of.close(); 


	//find out validate points
	double mean = 0;
	vector<double>::iterator iter = distance.begin();
	while (iter != distance.end())
	{
		mean += *iter;
		iter++;
	}
	mean /= distance.size();

	vector<Point> validPoints;
	for (int i = 0; i < distance.size(); i++)
	{
		if (distance.at(i) < mean)
		{
			validPoints.push_back(points.at(2 * i));
			validPoints.push_back(points.at(2 * i + 1));
		}
	}

	//figure out the center and radius of the circle with Kasa method

	if (!CircleFitByKasa(validPoints, center, radius))
	{
		cout << "Revisied LineScan Method Failed, Because the Circle Fit Method failed!" << endl;
		return;
	}

	//#ifdef _DEBUG_
	cout << "Use the Revised ScanLine Method:" << endl
		<< "\tThe center is (" << center.x << ", "
		<< center.y << ")" << endl
		<< "\tThe radius is " << radius << endl;

	circle(src, center, radius, Scalar(0, 0, 255), src.cols / 300);
	circle(src, center, 5, Scalar(0, 255, 255), -1);

	//namedWindow("Revised ScanLine Method Result", CV_WINDOW_AUTOSIZE);
	//imshow("Revised ScanLine Method Result", src);
	imshow(win_name, src);
	//imwrite("Revised_Scan_ret.tiff", src);
	//waitKey();
	//#endif

}