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

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