Как определить угол контура с учетом его кривизны в OpenCVC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как определить угол контура с учетом его кривизны в OpenCV

Сообщение Anonymous »

Мне нужно вычислить угол контура в диапазоне от -180 до 180 градусов, принимая во внимание направление его кривизны.
Я нашел соответствующую публикацию Stack Overflow и реализовал следующий код для расчета угла, но с его помощью я не знаю, как учитывать направление кривизны контура.
Я также пытался вычислить угол изгиба, используя начало и конец контура точки и центр тяжести.
Однако мне сложно определить угол контура, учитывая его кривизну.

Код: Выделить всё

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

double distanceBtwPoints(const cv::Point2f& a, const cv::Point2f& b)
{
double xDiff = a.x - b.x;
double yDiff = a.y - b.y;

return std::sqrt((xDiff * xDiff) + (yDiff * yDiff));
}

double get_angle(const cv::Point& p1, const cv::Point& p2) {
return std::atan2(p1.y - p2.y, p1.x - p2.x) * 180 / CV_PI;
}

void calculateAngle(cv::Mat& edgeImage) {
vector contours;
vector hierarchy;
findContours(edgeImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_NONE);

cv::Mat drawing = cv::Mat::zeros(edgeImage.size(), CV_8UC3);

RotatedRect _minAreaRect;
for (int i = 0; i < contours.size(); i = hierarchy[i][0])
{
_minAreaRect = minAreaRect(Mat(contours[i]));
Point2f pts[4];
_minAreaRect.points(pts);

double dist0 = distanceBtwPoints(pts[0], pts[1]);
double dist1 = distanceBtwPoints(pts[1], pts[2]);

double angle = 0;
if (dist0 > dist1 * 2)
{
angle = atan2(pts[0].y - pts[1].y, pts[0].x - pts[1].x) * 180.0 / CV_PI;
}
if (dist1 > dist0 * 2) {
angle = atan2(pts[1].y - pts[2].y, pts[1].x - pts[2].x) * 180.0 / CV_PI;
}

putText(drawing, to_string(angle), centroid, FONT_HERSHEY_SIMPLEX, 1.5, Scalar(255, 255, 255), 2);

Moments mu = moments(contours[i], true);
Point2f centroid(mu.m10 / mu.m00, mu.m01 / mu.m00);

std::vector approx;
cv::approxPolyDP(contours[i], approx, 0.2 * cv::arcLength(contours[i], true), true);
Point2f contour_start = approx.front();
Point2f contour_end = approx.back();

double angle_start = get_angle(centroid, contour_start);
double angle_end = get_angle(centroid, contour_end);
double bending_angle = angle_end - angle_start;

circle(drawing, centroid, 15, Scalar(255, 255, 255), -1);
circle(drawing, contour_start, 15, Scalar(255, 255, 255), -1);
circle(drawing, contour_end, 15, Scalar(255, 255, 255), -1);

// Normalize the angle to the range [-180, 180)
if (bending_angle > 180) {
bending_angle -= 360;
}
else if (bending_angle < -180) {
bending_angle += 360;
}

for (int j = 0; j < 4; j++)
line(drawing, pts[j], pts[(j + 1) % 4], Scalar(0, 0, 255), 3, LINE_AA);

drawContours(drawing, contours, i, Scalar(0, 0, 255), 2);

circle(drawing, centroid, 15, Scalar(255, 255, 255), -1);
line(drawing, centroid, contour_start, Scalar(255, 0, 0), 2);
line(drawing, centroid, contour_end, Scalar(255, 0, 0), 2);

//putText(drawing, to_string(bending_angle ), centroid, FONT_HERSHEY_SIMPLEX, 1.5, Scalar(255, 255, 255), 2);

}
cv::namedWindow("angle", cv::WINDOW_NORMAL);
cv::resizeWindow("angle", 700, 700);
cv::imshow("angle", drawing);
cv::waitKey(0);
cv::destroyAllWindows();
}

int main() {
cv::Mat img = cv::imread("angletest.bmp");
if (img.empty()) {
std::cout 

Подробнее здесь: [url]https://stackoverflow.com/questions/78809415/how-to-determine-the-angle-of-a-contour-considering-its-curvature-in-opencv[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»