• OpenCV25-判断一个点是否在多边形的内部_点多边形测试pointPolygonTest


    OpenCV25-判断一个点是否在多边形的内部_点多边形测试pointPolygonTest
    opencv函数
    
    pointPolygonTest:
    
    C++: double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)
    
    用于测试一个点是否在多边形中
    当measureDist设置为true时,返回实际距离值。若返回值为正,表示点在多边形内部,返回值为负,表示在多边形外部,返回值为0,表示在多边形上。
    当measureDist设置为false时,返回 -1、0、1三个固定值。若返回值为+1,表示点在多边形内部,返回值为-1,表示在多边形外部,返回值为0,表示在多边形上
    
    pointPolygonTest(
    InputArray  contour,// 输入的轮廓
    Point2f  pt, // 测试点
    bool  measureDist // 是否返回距离值,如果是false,1表示在内面,0表示在边界上,-1表示在外部,true返回实际距离
    )
    
    返回数据是double类型
    
    步骤:
    
    发现轮廓
    对图像中所有像素点做点 多边形测试,得到距离,归一化后显示。
    
    
    OpenCV Error: Assertion failed ((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())) in cv::Mat::at, file d:opencv3opencvuildincludeopencv2coremat.inl.hpp, line 918
    表示操作通道数错误,本来是单通道,却操作了多通道。
    //Mat drawImg1 = Mat::zeros(src.size(),CV_8UC1);//错误
    Mat drawImg1 = Mat::zeros(src.size(), CV_8UC3);
    */
    #include <iostream>
    #include <opencv2opencv.hpp>
    
    
    using namespace std;
    using namespace cv;
    int main(int argc, char *argv[])
    {
        Mat src = imread("e:\pictures\五角星.jpg");
        //Mat src = imread("e:\pictures\牡丹花.jpg",CV_LOAD_IMAGE_COLOR);
        
        if (!src.data)
        {
            printf("failed to load image");
            return -1;
        }
        //namedWindow("原图",CV_WINDOW_AUTOSIZE);
        imshow("原图",src);
        
        threshold(src,src,126,255,CV_THRESH_BINARY);//二值化
        //转灰度图像
        cvtColor(src,src,CV_BGR2GRAY);
        vector<vector<Point>> contours;
        vector<Vec4i> hierachy;
        //发现轮廓
        findContours(src,contours,hierachy,RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
        //画轮廓
        drawContours(src,contours,1,Scalar::all(255),2,8,hierachy);
    
        imshow("轮廓",src);
    
        //waitKey();
        //return 0;
    
        //距离
        Mat dist = Mat::zeros(src.size(),CV_32FC1);
        for (int i = 0; i < src.rows; i++)
        {
            for (int j = 0; j < src.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(src.size(),CV_8UC1);//错误
        Mat drawImg1 = Mat::zeros(src.size(), CV_8UC3);
        int thredVal1 = 1;
        for (int i = 0; i < src.rows; i++)
        {
            for (int j = 0; j < src.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("drawImag1",drawImg1);
        //imwrite("drawImg1.jpg",drawImg1);//保存图像
    
        //归一化
        normalize(dist,dist,-255,255,NORM_MINMAX);
        Mat drawImg2 = Mat::zeros(src.size(),CV_8UC3);
        int thredVal2 = 3;
        for (int i = 0; i < src.rows; i++)
        {
            for (int j = 0; j < src.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);
        waitKey();
        return 0;
    
    }
    欢迎讨论,相互学习。 txwtech@163.com
  • 相关阅读:
    POJ3233 构造子矩阵+矩阵快速幂
    HDU4565-数学推导求递推公式+矩阵快速幂
    记录一个状压DP用到的骚操作
    POJ1273 最大流模板
    图论复习...
    2017-7 实训经验贴
    Polya定理应用实例
    直线,椭圆,三角形,折线分割平面问题
    hdu4801 PocketCube 2阶魔方
    1256:献给阿尔吉侬的花束
  • 原文地址:https://www.cnblogs.com/txwtech/p/14706949.html
Copyright © 2020-2023  润新知