Anonymous
Как определить угол контура с учетом его кривизны в OpenCV
Сообщение
Anonymous » 30 июл 2024, 03:38
Мне нужно вычислить угол контура в диапазоне от -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]
1722299907
Anonymous
Мне нужно вычислить угол контура в диапазоне от -180 до 180 градусов, принимая во внимание направление его кривизны. Я нашел соответствующую публикацию Stack Overflow и реализовал следующий код для расчета угла, но с его помощью я не знаю, как учитывать направление кривизны контура. Я также пытался вычислить угол изгиба, используя начало и конец контура точки и центр тяжести. Однако мне сложно определить угол контура, учитывая его кривизну. [code]#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]