要判断一个轮廓是否在圆环内,可以将问题分解为两个步骤:
- 确保轮廓的所有点都在外圆内。
- 确保轮廓的所有点都在内圆外。
下面是一个完整的示例代码,展示如何实现这一点:
#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
函数:- 该函数检查一个轮廓的所有点是否都在指定的圆环内。轮廓的每个点必须在外圆内且在内圆外。