imgproc模块--多边形测试

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);
}

参考文献
1.http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/shapedescriptors/point_polygon_test/point_polygon_test.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章