Определение угла emgucv для прямоугольника в csharp - PullRequest
0 голосов
/ 18 июня 2020

Я использую следующий поток для определения угла для прямоугольного изображения. Определение центра и угла прямоугольников в изображении с помощью Opencv

Я застрял в следующем фрагменте кода.

cv::Point2f edge1 = cv::Vec2f(rect_points[1].x, rect_points[1].y) - cv::Vec2f(rect_points[0].x, rect_points[0].y);
cv::Point2f edge2 = cv::Vec2f(rect_points[2].x, rect_points[2].y) - cv::Vec2f(rect_points[1].x, rect_points[1].y);

cv::Point2f usedEdge = edge1;
if(cv::norm(edge2) > cv::norm(edge1)) usedEdge = edge2;

cv::Point2f reference = cv::Vec2f(1,0); // horizontal edge

angle = 180.0f/CV_PI * acos((reference.x*usedEdge.x + reference.y*usedEdge.y) / (cv::norm(reference) *cv::norm(usedEdge)));

Я не могу понять следующие несколько строки, которые мне нужно было преобразовать в emgu csharp.

cv::Point2f edge1 = cv::Vec2f(rect_points[1].x, rect_points[1].y) - cv::Vec2f(rect_points[0].x, rect_points[0].y);
cv::Point2f edge2 = cv::Vec2f(rect_points[2].x, rect_points[2].y) - cv::Vec2f(rect_points[1].x, rect_points[1].y);

angle = 180.0f/CV_PI * acos((reference.x*usedEdge.x + reference.y*usedEdge.y) / (cv::norm(reference) *cv::norm(usedEdge)));
if(cv::norm(edge2) > cv::norm(edge1)) usedEdge = edge2;
cv::Point2f reference = cv::Vec2f(1,0); 

Может ли кто-нибудь помочь мне, как решить то же самое? Любая помощь или предложение будут высоко оценены?

1 Ответ

2 голосов
/ 19 июня 2020

Здесь Point2f - это просто точки со свойствами точности с плавающей запятой X и Y, используемые для хранения 2D-векторов I и J. Их метод объявления if устанавливает ребра как вектор между двумя точками, то есть дельту между этими двумя точками. В C# я бы написал это как:

float deltaX = rect_points[1].X - rect_points[0].X;
float deltaY = rect_points[1].Y - rect_points[0].Y;
PointF edge1 = new PointF(deltaX, deltaY);

OR конечно ...

PointF edge1 = new PointF(rect_points[1].X - rect_points[0].X, rect_points[1].Y - rect_points[0].Y);
PointF edge2 = new PointF(rect_points[2].X - rect_points[1].X, rect_points[2].Y - rect_points[1].Y);

Эти PointF теперь являются двумя векторами , или ребра, которые соединяются в rect_points[1]. Затем выполняется norm, чтобы сравнить величину двух. Это просто Пифагор, если мы проделаем то же самое вручную:

edge1Magnitude = Math.Sqrt(Math.Pow(edge1.X, 2) + Math.Pow(edge1.Y, 2));
edge2Magnitude = Math.Sqrt(Math.Pow(edge2.X, 2) + Math.Pow(edge2.Y, 2));

Более длинный край, имеющий наибольшую величину, считается «основным», или более длинный край прямоугольника:

PointF primaryEdge = edge1Magnitude > edge2Magnitude ? edge1 : edge2;
double primaryMagnitude = edge1Magnitude > edge2Magnitude ? edge1Magnitude : edge2Magnitude;

Наконец, чтобы найти угол между primaryEdge и горизонтальным вектором reference. Это acos, «точечного произведения» двух, или:

PointF reference = new PointF(1,0);
double refMagnitude = 1;
double thetaRads = Math.Acos(((primaryEdge.X * reference.X) + (primaryEdge.Y * reference.Y)) / (primaryMagnitude * refMagnitude));
double thetaDeg = thetaRads * 180 / Math.PI;

Теперь thetaDeg - это угол между edge1 и горизонталью в градусах.

...