2020年6月14日 星期日

OpenCV EllipseRect(橢圓擬合功能)

如果想將影像中的圖形,擬合成橢圓形並畫出來,那要怎麼做呢?
使用到下列的函式fitEllipse,可以將findContours算出來的contours作為輸入
並用RotatedRect的函式去接橢圓形的資訊。

C++: RotatedRect fitEllipse(InputArray points)

//---------------------------------------------程式碼-------------------------------------------------
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(){

	Mat PatternImg = imread("Pattern1.png", CV_LOAD_IMAGE_COLOR);
	Mat GrayImg, BinaryImg;
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;
	resize(PatternImg, PatternImg, Size(), 0.5, 0.5);
	cvtColor(PatternImg, GrayImg, CV_BGR2GRAY);
	threshold(GrayImg, BinaryImg, 125, 255, CV_THRESH_BINARY);

	findContours(BinaryImg, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point(0, 0));

	Point2f LongPtA1, LongPtA2, ShortPtB1, ShortPtB2;
	for (int i = 0; i< contours.size(); i++)
	{
		if (contours[i].size()<=5)
			continue;
		RotatedRect EllipseRect = fitEllipse(contours[i]);
		
		float Angle = (EllipseRect.angle - 90) * 3.1415972 / 180.0;

		LongPtA1.x = EllipseRect.center.x + cos(Angle)*EllipseRect.size.height / 2;
		LongPtA1.y = EllipseRect.center.y + sin(Angle)*EllipseRect.size.height / 2;
		LongPtA2.x = EllipseRect.center.x - cos(Angle)*EllipseRect.size.height / 2;
		LongPtA2.y = EllipseRect.center.y - sin(Angle)*EllipseRect.size.height / 2;

		ShortPtB1.x = EllipseRect.center.x + sin(-Angle)*EllipseRect.size.width / 2;
		ShortPtB1.y = EllipseRect.center.y + cos(-Angle)*EllipseRect.size.width / 2;
		ShortPtB2.x = EllipseRect.center.x - sin(-Angle)*EllipseRect.size.width / 2;
		ShortPtB2.y = EllipseRect.center.y - cos(-Angle)*EllipseRect.size.width / 2;

		ellipse(PatternImg, EllipseRect, Scalar(0, 0, 255), 2, CV_AA);

		circle(PatternImg, Point(EllipseRect.center.x, EllipseRect.center.y), 5, Scalar(0, 0, 255), -1);
		circle(PatternImg, LongPtA1, 3, Scalar(0, 255, 255), -1);
		circle(PatternImg, LongPtA2, 3, Scalar(0, 255, 255), -1);
		circle(PatternImg, ShortPtB1, 3, Scalar(255, 255, 0), -1);
		circle(PatternImg, ShortPtB2, 3, Scalar(255, 255, 0), -1);
	}
	
	imshow("ResultImg", PatternImg);
	imwrite("ResultImg.bmp", PatternImg);
	waitKey(0);
	return 0;
}
//---------------------------------------------程式碼-------------------------------------------------
結果圖