OpenCV结构分析与形状描述符(23)确定一个点是否位于多边形内的函数pointPolygonTest()的使用
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
进行点在轮廓内的测试。
该函数确定点是在轮廓内、轮廓外,还是位于一条边上(或与顶点重合)。它返回正值(内部)、负值(外部),或零值(在一条边上)。当 measureDist=false 时,返回值分别是 +1(内部)、-1(外部)和 0(在一条边上)。否则,返回值是从点到最近轮廓边的带符号距离。
下面是一个函数样本输出,其中每个图像像素都经过了轮廓测试:
函数原型
double cv::pointPolygonTest
(
InputArray contour,
Point2f pt,
bool measureDist
)
参数
- 参数contour 输入的轮廓。
- 参数pt 要测试的点。
- 参数measureDist 如果为 true,则函数估计点到最近轮廓边缘的带符号距离。否则,函数只检查点是否在轮廓内部。
返回值
- 当 measureDist=false 时,返回值是:
- +1:如果点在轮廓内部。
- -1:如果点在轮廓外部。
- 0:如果点在轮廓的边上或与顶点重合。
- 当 measureDist=true 时,返回值是从点到最近轮廓边的带符号距离。距离为正表示点在轮廓内部,距离为负表示点在轮廓外部,距离为零表示点在轮廓边上或与顶点重合。
代码示例
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
// 创建一个空白的图像
cv::Mat image = cv::Mat::zeros( 300, 300, CV_8UC3 );
// 创建一个示例轮廓
std::vector< cv::Point > contour;
contour.push_back( cv::Point( 100, 100 ) );
contour.push_back( cv::Point( 200, 100 ) );
contour.push_back( cv::Point( 200, 200 ) );
contour.push_back( cv::Point( 100, 200 ) );
// 绘制轮廓
std::vector<std::vector<cv::Point>> contours(1, contour);
cv::drawContours(image, contours, 0, cv::Scalar(0, 255, 0), 2); // 在三通道图像的第一个轮廓上绘制绿色线条
// 显示原始图像
cv::imshow( "Original Image", image );
// 创建一个掩码图像
cv::Mat mask = cv::Mat::zeros( image.size(), CV_8UC1 );
// 遍历每个像素并测试其位置
for ( int y = 0; y < image.rows; ++y )
{
for ( int x = 0; x < image.cols; ++x )
{
cv::Point2f pixel( x, y );
float result = cv::pointPolygonTest( contour, pixel, false );
if ( result >= 0 )
{
mask.at< uchar >( y, x ) = 255; // 内部 如果点在轮廓内部,则在掩码图像上标记为白色(255)。
}
else
{
mask.at< uchar >( y, x ) = 125; // 内部
}
}
}
// 显示掩码图像
cv::imshow( "Mask Image", mask );
cv::waitKey( 0 );
return 0;
}