1.目的
(1)使用openCV函数pointPolygonTest进行多边形测试
2.部分代码解释
(1)pointPolygonTest
/**/
/*
pointPolygonTest参数解释
contours[0]:测试轮廓
Point:测试点
measureDist:bool变量,true:则函数估计点到最近轮廓边缘的距离,false:检测点是否在边缘轮廓中
*/
//PS:pointPolygonTest函数返回值根据measureDist确定,
//measureDist为true,函数返回点到最近边缘轮廓的距离,正数(inside),负数(outside),零(on an edge)
//measureDist为false,函数返回点到最近边缘轮廓的情况,1(inside),-1(outside),0(on an edge)
src_dist.at<float>(i,j) = pointPolygonTest(contours[0], Point2f(j,i), true);
3.完整代码
(1)CommonInclude.h
#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
#endif
(2)PolygonTest.cpp
#include "CommonInclude.h"
/** @function main */
int main( int argc, char** argv )
{
// 创建一个图形
const int r = 100;
Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8UC1 );
// 绘制一系列点创建一个轮廓:
vector<Point2f> vert(6);
vert[0] = Point( 1.5*r, 1.34*r );
vert[1] = Point( 1*r, 2*r );
vert[2] = Point( 1.5*r, 2.866*r );
vert[3] = Point( 2.5*r, 2.866*r );
vert[4] = Point( 3*r, 2*r );
vert[5] = Point( 2.5*r, 1.34*r );
// 在src内部绘制
for( int j = 0; j < 6; j++ )
{
line( src, vert[j], vert[(j+1)%6], Scalar( 255 ), 3, 8 );
}
// 得到轮廓
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Mat src_copy = src.clone();
findContours( src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
// 计算到轮廓的距离
Mat src_dist = Mat(src.size(), CV_32FC1);
for(int i=0; i<src_dist.rows; i++){
for(int j=0; j<src_dist.cols; j++){
/*
pointPolygonTest参数解释
contours[0]:测试轮廓
Point:测试点
measureDist:bool变量,true:则函数估计点到最近轮廓边缘的距离,false:检测点是否在边缘轮廓中
*/
//PS:pointPolygonTest函数返回值根据measureDist确定,
//measureDist为true,函数返回点到最近边缘轮廓的距离,正数(inside),负数(outside),零(on an edge)
//measureDist为false,函数返回点到最近边缘轮廓的情况,1(inside),-1(outside),0(on an edge)
src_dist.at<float>(i,j) = pointPolygonTest(contours[0], Point2f(j,i), true);
}
}
double minVal; double maxVal;
minMaxLoc( src_dist, &minVal, &maxVal, 0, 0, Mat());
minVal = abs(minVal); maxVal = abs(maxVal);
// 图形化的显示距离
Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
for( int j = 0; j < src.rows; j++ )
{
for( int i = 0; i < src.cols; i++ )
{
//在轮廓中
if( src_dist.at<float>(j,i) < 0 )
{
drawing.at<Vec3b>(j,i)[0] = 255 - (int) abs(src_dist.at<float>(j,i))*255/minVal;
}else if( src_dist.at<float>(j,i) > 0 ){
//在轮廓外
drawing.at<Vec3b>(j,i)[2] = 255 - (int) src_dist.at<float>(j,i)*255/maxVal;
}
else{
//在轮廓上
drawing.at<Vec3b>(j,i)[0] = 255;
drawing.at<Vec3b>(j,i)[1] = 255;
drawing.at<Vec3b>(j,i)[2] = 255;
}
}
}
// 创建窗口显示结果
char source_window[] = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
namedWindow( "Distance", CV_WINDOW_AUTOSIZE );
imshow( "Distance", drawing );
waitKey(0);
return(0);
}