设为首页收藏本站 |天气与日历| 2025-04-19 星期六 13:30:00 乙巳(蛇)年 三月廿二 未时
     
切换到窄版

私人站点

 找回密码
 立即注册
搜索
查看: 406|回复: 0

点多边形测试

[复制链接]

954

主题

954

帖子

3875

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3875
发表于 2022-3-17 12:28:23 | 显示全部楼层 |阅读模式
概念介绍 - 点多边形测试 - 测试一个点是否在给定的多边形内部,边缘或者外部

1.png 2.png




API介绍 cv::pointPolygonTest

pointPolygonTest(
InputArray  contour,// 输入的轮廓
Point2f  pt, // 测试点
bool  measureDist // 是否返回距离值,如果是false,1表示在内面,0表示在边界上,-1表示在外部,true返回实际距离
)

返回数据是double类型




处理步骤:

  • 构建一张400x400大小的图片, Mat::Zero(400, 400, CV_8UC1)
  • 画上一个六边形的闭合区域line
  • 发现轮廓
  • 对图像中所有像素点做点 多边形测试,得到距离,归一化后显示。






[C++] 纯文本查看 复制代码
/*
注意:

*/
#include <opencv2/opencv.hpp>
#include <iostream>
#include<math.h>
using namespace std;
using namespace cv;

Mat src, dst, gray,csrc;


int main(int argc, char** argv) {

	const int r = 100;
	//将SRC 初始化测过400 乘400  的八位单通道 图片
	Mat src = Mat::zeros(r * 4, r * 4, CV_8UC1);

	//定义点
	vector<Point2f>vert(6);
	vert[0] = Point(3 * r / 2, static_cast<int>(1.34 * r));
	vert[1] = Point(r,2 * r);
	vert[2] = Point(3*r/2, static_cast<int>(2.866 * r));
	vert[3] = Point(5 * r / 2, static_cast<int>(2.866 * r));
	vert[4] = Point(3 * r, 2 * r);
	vert[5] = Point(5*r/2, static_cast<int>(1.34 * r));
	
	//画6条线
	for (int i = 0; i <6; i++)
	{
		line(src, vert[i], vert[((i + 1) % 6)], Scalar(255, 0, 0), 3, 8, 0);
	}


	vector<vector<Point>> contours;
	//定义层次
	vector<Vec4i>hierachy;
	src.copyTo(csrc);
	//轮廓发现
	findContours(csrc, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0 ));
	Mat raw_dist = Mat::zeros(csrc.size(), CV_32FC1);
	for (int row = 0; row < raw_dist.rows; row++) {
		for (int  col = 0; col < raw_dist.cols; col++)
		{
			//距离测试
			double dist = pointPolygonTest(contours[0], Point2f(static_cast<float>(col), static_cast<float>(row)), true);
			raw_dist.at<float>(row, col) = static_cast<float>(dist);

		}
	
	}


	//定义最大最小值
	double minValue, maxValue;
	//找到最大和最小值
	minMaxLoc(raw_dist, &minValue, &maxValue, 0, 0, Mat());
	Mat drawimg = Mat::zeros(src.size(), CV_8UC3);

	for (int row = 0; row < drawimg.rows; row++) {
		for (int col = 0; col < drawimg.cols; col++)
		{
			float dist = raw_dist.at<float>(row, col);

			if (dist > 0) {
				//内部
				drawimg.at<Vec3b>(row, col)[0] = (uchar)(abs(1.0 - (dist / maxValue)) * 255);
			}
			else if (dist < 0) {
				//外部
				drawimg.at<Vec3b>(row, col)[2] = (uchar)(abs(1.0 - (dist / minValue)) * 255);
			}
			else {
				//边缘线
				drawimg.at<Vec3b>(row, col)[0] = (uchar)(abs(255 - dist));
				drawimg.at<Vec3b>(row, col)[1] = (uchar)(abs(255 - dist));
				drawimg.at<Vec3b>(row, col)[2] = (uchar)(abs(255 - dist));
			}
		}
	}

	imshow("input", src);
	imshow("output", drawimg);

	waitKey(0);
	return 0;
}




33333.jpg







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|编程站点 ( 冀ICP备2023028127号-2 )|友链申请|

GMT+8, 2025-4-19 13:30 , Processed in 0.096158 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表