要判断一个轮廓是否在圆环内,可以将问题分解为两个步骤:
- 确保轮廓的所有点都在外圆内。
- 确保轮廓的所有点都在内圆外。
下面是一个完整的示例代码,展示如何实现这一点:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <cmath>using namespace cv;
using namespace std;// 检查一个点是否在圆内
bool point_inside_circle(const Point& point, const Point& center, double radius)
{double distance = norm(point - center);return distance <= radius;
}// 检查一个点是否在圆外
bool point_outside_circle(const Point& point, const Point& center, double radius)
{double distance = norm(point - center);return distance >= radius;
}// 检查轮廓是否在圆环内
bool contour_inside_annulus(const vector<Point>& contour, const Point& center, double innerRadius, double outerRadius)
{for (const auto& point : contour){if (!point_inside_circle(point, center, outerRadius) || !point_outside_circle(point, center, innerRadius)) {return false; // 如果任何点不在圆环内,返回 false}}return true; // 所有点都在圆环内,返回 true
}int main()
{// 定义圆心和半径Point center(200, 200);double innerRadius = 40.0;double outerRadius = 180.0;cv::Mat cv_src(cv::Size(640, 640), CV_8UC3, cv::Scalar(255, 255, 255));cv::circle(cv_src, center, innerRadius, cv::Scalar(0, 0, 0), 1, cv::LINE_AA);cv::circle(cv_src, center, outerRadius, cv::Scalar(0, 0, 0), 1, cv::LINE_AA);cv::imshow("src", cv_src);// 创建一个轮廓vector<Point> contour = { Point(80, 100), Point(200, 100), Point(120, 240), Point(100, 200) };cv::drawContours(cv_src, std::vector<std::vector<cv::Point>>{contour}, -1, cv::Scalar(255, 0, 0), 1);// 检查轮廓是否在圆环内if (contour_inside_annulus(contour, center, innerRadius, outerRadius)) {cout << "Contour inside annulus!" << endl;}else {cout << "Contour no inside annulus!" << endl;}cv::imshow("dst", cv_src);cv::waitKey(0);return 0;
}
演示结果:
可以调整内圆的圆心,来演示不包含轮廓点:
double innerRadius = 100.0;
double outerRadius = 180.0;
代码说明
-
point_inside_circle
函数:- 该函数检查一个点是否在指定圆内。计算点到圆心的距离,如果距离小于等于半径,则点在圆内。
-
point_outside_circle
函数:- 该函数检查一个点是否在指定圆外。计算点到圆心的距离,如果距离大于等于半径,则点在圆外。
-
contour_inside_annulus
函数:- 该函数检查一个轮廓的所有点是否都在指定的圆环内。轮廓的每个点必须在外圆内且在内圆外。