OpenCV学习三十三:pointPolygonTest 检测点是否在轮廓内
Posted Thomas会写字
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV学习三十三:pointPolygonTest 检测点是否在轮廓内相关的知识,希望对你有一定的参考价值。
opencv函数
pointPolygonTest:
C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)
用于测试一个点是否在多边形中
当measureDist设置为true时,返回实际距离值。若返回值为正,表示点在多边形内部,返回值为负,表示在多边形外部,返回值为0,表示在多边形上。
当measureDist设置为false时,返回 -1、0、1三个固定值。若返回值为+1,表示点在多边形内部,返回值为-1,表示在多边形外部,返回值为0,表示在多边形上。
#include <opencv2/opencv.hpp>
#include "iostream"
using namespace std;
using namespace cv;
int main( int argc, char** argv )
Mat img = imread("fengye.jpg");
threshold(img, img, 127, 255, CV_THRESH_BINARY);
cvtColor(img ,img ,CV_BGR2GRAY);
vector<vector<Point>> contours;
vector<Vec4i> hierachy;
findContours(img, contours, hierachy, RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
drawContours(img, contours, 1, Scalar::all(255), 2, 8, hierachy);
//这里说明下,轮廓1是圈出的枫叶
Mat dist = Mat::zeros(img.size(), CV_32FC1);
for (int i=0; i<img.rows; i++)
for (int j=0; j<img.cols; j++)
double distance = pointPolygonTest(contours[1], Point2f(j, i), true);
dist.at<float>(i, j) = static_cast<float>(distance);
double minVal, maxVal;
minMaxLoc(dist, &minVal, &maxVal, 0, 0, Mat());
Mat drawImg1 = Mat::zeros(img.size(), CV_8UC3);
int thredVal1 = 1;
for (int i=0; i<img.rows; i++)
for (int j=0; j<img.cols; j++)
double distance = dist.at<float>(i,j);
if (distance > thredVal1)
drawImg1.at<Vec3b>(i,j)[0] = (uchar)(abs(distance/maxVal)*255);
else if (distance < (thredVal1 *(-1)) )
drawImg1.at<Vec3b>(i,j)[2] = (uchar)(abs(distance/minVal)*255);
else
drawImg1.at<Vec3b>(i,j)[0] = (uchar)(abs(255-distance));
drawImg1.at<Vec3b>(i,j)[1] = (uchar)(abs(255-distance));
drawImg1.at<Vec3b>(i,j)[2] = (uchar)(abs(255-distance));
imshow("drawImg1", drawImg1);
imwrite("drawImg1.jpg", drawImg1);
normalize(dist, dist, -255, 255, NORM_MINMAX);
Mat drawImg2 = Mat::zeros(img.size(), CV_8UC3);
int thredVal2 = 3;
for (int i=0; i<img.rows; i++)
for (int j=0; j<img.cols; j++)
double distance = dist.at<float>(i,j);
if (distance > thredVal2)
drawImg2.at<Vec3b>(i,j)[0] = (uchar)(distance);
else if (distance < (thredVal2 *(-1)) )
drawImg2.at<Vec3b>(i,j)[2] = (uchar)(distance*(-1));
else
drawImg2.at<Vec3b>(i,j)[0] = (uchar)(255);
drawImg2.at<Vec3b>(i,j)[1] = (uchar)(255);
drawImg2.at<Vec3b>(i,j)[2] = (uchar)(255);
imshow("drawImg2", drawImg2);
imwrite("drawImg2.jpg", drawImg2);
imshow("img", img);
waitKey();
return 0;
原图
drawImg1
drawImg2
说明下:白色线的位置差异是由于归一化的方式不同,在第一种方式中肯定可以锁定到轮廓上,在第二种方式中由于最大最小距离的绝对值不同。
以上是关于OpenCV学习三十三:pointPolygonTest 检测点是否在轮廓内的主要内容,如果未能解决你的问题,请参考以下文章