精华内容
下载资源
问答
  • OpenCV多边形逼近轮廓

    千次阅读 2019-08-30 11:36:51
    当我们查找到一个轮廓进行形状分析时,通常需要使用多边形来逼近一个轮廓,使得顶点数变少,OpenCV的approxPolyDP函数就可以实现这个功能。 approxPolyDP函数使用了Douglas-Peucker算法: 1、先从轮廓中找出两个最...

    当我们查找到一个轮廓进行形状分析时,通常需要使用多边形来逼近一个轮廓,使得顶点数变少,OpenCV的approxPolyDP函数就可以实现这个功能。

    approxPolyDP函数使用了Douglas-Peucker算法:

    1、先从轮廓中找出两个最远的点,将两点相连,即b-c;

    2、在原来的轮廓上查找一个离线段距离最远的点,将该点加入逼近后的新轮廓中,即c-d;

    3、然后重复前面的算法,不断迭代,将最远的点添加进来,直到所有的点到多边形的最短距离小于指定的精度。

    函数原型 

    void approxPolyDP( InputArray curve,OutputArray approxCurve,double epsilon, bool closed );

    参数解析:

    • curve:存储在std :: vector或Mat中的2D点的输入向量,一般是轮廓点的集合。
    • approxCurve:输出拟合的多边形点集, 类型应与输入曲线的类型相同。
    • epsilon:指定近似精度的参数, 这是原始曲线和它的近似之间最大距离。
    • closed:如果为true,则闭合近似曲线(其第一个和最后一个顶点为连接的);否则,不闭合。

    关键代码

    #include <opencv2/opencv.hpp>
    #include <iostream>
    using namespace cv;
    using namespace std;
    
    //定义颜色常量
    const cv::Scalar RED = cv::Scalar(0, 0, 255);					//红色
    const cv::Scalar PINK = cv::Scalar(230, 130, 255);				//粉色
    const cv::Scalar BLUE = cv::Scalar(255, 0, 0);					//蓝色
    const cv::Scalar LIGHTBLUE = cv::Scalar(255, 255, 160);			//亮蓝色
    const cv::Scalar GREEN = cv::Scalar(0, 255, 0);					//绿色
    const cv::Scalar YELLOW = cv::Scalar(175, 255, 255);			//黄色
    const cv::Scalar DEEP_SKYBLUE = cv::Scalar(0, 191, 255);		//深天空蓝
    const cv::Scalar ORCHID = cv::Scalar(218, 112, 214);			//兰花
    const cv::Scalar WHITE = cv::Scalar(255, 255, 255);				//白色
    
    int main()
    {
    	Mat srcImage, grayImage, binaryImage;
    	srcImage = imread("OpenCV.jpg",1);
    	resize(srcImage, srcImage,Size(srcImage.cols/2,srcImage.rows/2));
    	
    	Mat dstImage_3(srcImage.size(), CV_8UC3, Scalar::all(0));
    	Mat dstImage_5(srcImage.size(), CV_8UC3, Scalar::all(0));
    	Mat dstImage_8(srcImage.size(), CV_8UC3, Scalar::all(0));
    	
    	cvtColor(srcImage, grayImage,COLOR_RGB2GRAY);
    	imshow("grayImage", grayImage);
    	
    	threshold(grayImage, binaryImage,200,255, THRESH_BINARY_INV);
    	imshow("binaryImage", binaryImage);
    	
    	vector<vector<Point>> contours;
    	findContours(binaryImage, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
    	
    	vector<vector<Point>> contours_ploy(contours.size());
    	for (int i=0;i<contours.size();i++)
    	{
    		drawContours(srcImage, contours, i, Scalar(230, 130, 255), 1, CV_AA);
    		//epsilon==3
    		approxPolyDP(Mat(contours[i]), contours_ploy[i], 3, true);
    		drawContours(dstImage_3, contours_ploy, i, PINK, 1, CV_AA);
    		//epsilon==5
    		approxPolyDP(Mat(contours[i]), contours_ploy[i], 5, true);
    		drawContours(dstImage_5, contours_ploy, i, LIGHTBLUE, 1, CV_AA);
    		//epsilon==8
    		approxPolyDP(Mat(contours[i]), contours_ploy[i], 8, true);
    		drawContours(dstImage_8, contours_ploy, i, YELLOW, 1, CV_AA);
    	}
    	
    	imshow("srcImage", srcImage);
    	imshow("dstImage_3", dstImage_3);
    	imshow("dstImage_5", dstImage_5);
    	imshow("dstImage_8", dstImage_8);
    	
    	waitKey(0);
    	
    	destroyAllWindows();
    	
    	return 0;
    }

    从以上结果可以看出,设置的精度越小,多边形越拟合。

    展开全文
  • 输出结果 源码 #include <ostream> #include <opencv.hpp> #include <math.h> int main(int argc, char *argv[]) { /* 本章内容: 1. 轮廓查找 2. 绘制轮廓 3. 点多边形测试 ...

    本章内容:
            1. 轮廓查找
            2. 绘制轮廓
            3. 点多边形测试

    输出结果

    源码


    #include <ostream>
    #include <opencv.hpp>
    #include <math.h>

    int main(int argc, char *argv[])
    {
        /*
         本章内容:
            1. 轮廓查找
            2. 绘制轮廓
            3. 点多边形测试
        */
        cv::String fileName = "/home/wang/dev/Image/QT.jpg";
        cv::String fileName1 = "/home/wang/dev/Image/hei.png";
        cv::Mat src = cv::imread(fileName);
        cv::Mat src1 = cv::imread(fileName1);
        if(src.data == NULL){
            printf("图像读入失败\n");
            return -1;
        }
        cv::imshow("src",src);
        cv::Mat dstCany;
        cv::Mat gray;
        cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
        cv::Canny(gray,dstCany,50,150);
        std::vector<std::vector<cv::Point>> contours;
        std::vector<cv::Vec4i> hierarchy;
        cv::findContours(dstCany,contours,hierarchy,cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE,cv::Point(0,0));
        cv::RNG rng(1234);
        cv::Mat dst1(src.size(),CV_32FC1);
        // 点多边形测试
        for(int i=0;i<dst1.rows;i++){
            for(int j=0; j<dst1.cols;j++){
                cv::Point2f pt(i,j);
                double dist = cv::pointPolygonTest(contours[0],pt,true);
                dst1.at<float>(i,j) =dist;
            }
        }
        double minVal;
        double maxVal;
        cv::Mat dst(src.size(),CV_8UC3);
        cv::minMaxIdx(dst1,&minVal,&maxVal);
        for(int i=0;i<dst.rows;i++){
            for(int j=0; j<dst.cols;j++){
                float tem = dst1.at<float>(i,j);
                if(tem > 0) dst.at<cv::Vec3b>(i,j)[2] = tem / maxVal*255 ;
                else dst.at<cv::Vec3b>(i,j) = tem / minVal*255;

            }
        }
        //绘制曲线
        cv::Scalar color = cv::Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
        cv::drawContours(dst,contours,0,color,4);


        cv::imshow("dst",dst);
        cv::waitKey(0);
        return 1;
    }

     

    展开全文
  • 多边形将轮廓包围 返回外部矩形边界:boundingRect: ****返回的是包含轮廓的最小正矩阵 **** Rect cv :: boundingRect ( InputArray points ) 计算点集的右上边界矩形或灰度图像的非零像素。 该函数计算并返回...

    多边形将轮廓包围

    返回外部矩形边界:boundingRect:

    ****返回的是包含轮廓的最小正矩阵 ****

    Rect cv :: boundingRect ( InputArray points )

    计算点集的右上边界矩形或灰度图像的非零像素。

    该函数计算并返回指定点集的最小右上边界矩形或灰度图像的非零像素。
    参数(points):输入灰度图像或2D点集,存储在std :: vector或Mat中

    返回最小包围圆形:minEnclosingCircle:

    void cv::minEnclosingCircle	(	InputArray 	points,
    								Point2f & 	center,
    								float & 	radius 
    )	
    

    查找包含2D点集的最小区域的圆。

    该函数使用迭代算法找到2D点集的最小包围圆。

    • points 输入2D点的矢量,存储在std :: vector <>或Mat中
    • center 圆的输出中心.
    • radius 圆的输出半径.

    寻找最小包围矩形 minAreaRect:

    ****返回的是包含轮廓的最小斜矩形(有方向的) ****

    RotatedRect cv::minAreaRect ( InputArray points )

    查找包围输入2D点集的最小区域的旋转矩形。

    该函数计算并返回指定点集的最小区域边界矩形(可能旋转)。开发人员应该记住,当数据接近包含的Mat元素边界时,返回的RotatedRect可以包含负索引。

    参数(points):输入灰度图像或2D点集,存储在std :: vector或Mat中

    展开全文
  • opencv多边形检测

    千次阅读 2016-04-07 16:52:29
    示例代码为7边形,直接改宏定义即可#include "cv.h" #include "highgui.h" ...#include <string.h>#define SHAPE 7 //要检测的多边形边数////////////////////////////////////////////////////////////////

    示例代码为7边形,直接改宏定义即可

    #include <cv.h>
    #include <highgui.h>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    
    #define SHAPE 7 //要检测的多边形边数shape 检测形状 3为三角形,4矩形,5为五边形……
    
    //////////////////////////////////////////////////////////////////
    //函数功能:用向量来做COSα=两向量之积/两向量模的乘积求两条线段夹角
    //输入:   线段3个点坐标pt1,pt2,pt0,最后一个参数为公共点
    //输出:   线段夹角,单位为角度
    //////////////////////////////////////////////////////////////////
    double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 )
    {    
        double dx1 = pt1->x - pt0->x; 
        double dy1 = pt1->y - pt0->y;  
        double dx2 = pt2->x - pt0->x;  
        double dy2 = pt2->y - pt0->y;    
        double angle_line = (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);//余弦值
        return acos(angle_line)*180/3.141592653; 
    }
    //////////////////////////////////////////////////////////////////
    //函数功能:采用多边形逼近检测,通过约束条件寻找多边形
    //输入:   img 原图像
    //          storage 存储
    //          minarea,maxarea 检测多边形的最小/最大面积
    //          minangle,maxangle 检测多边形边夹角范围,单位为角度  
    //输出:   多边形序列
    //////////////////////////////////////////////////////////////////
    CvSeq* findSquares4( IplImage* img, CvMemStorage* storage ,int minarea, int maxarea, int minangle, int maxangle)
    {  
        CvSeq* contours;//边缘
        int N = 6;  //阈值分级
        CvSize sz = cvSize( img->width & -2, img->height & -2 );
        IplImage* timg = cvCloneImage( img );//拷贝一次img
        IplImage* gray = cvCreateImage( sz, 8, 1 ); //img灰度图
        IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 );  //金字塔滤波3通道图像中间变量
        IplImage* tgray = cvCreateImage( sz, 8, 1 ); ;   
        CvSeq* result;  
        double s, t;  
        CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );   
    
        cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height ));   
        //金字塔滤波 
        cvPyrDown( timg, pyr, 7 );  
        cvPyrUp( pyr, timg, 7 );   
        //在3个通道中寻找多边形 
        for( int c = 0; c < 3; c++ ) //对3个通道分别进行处理 
        {       
            cvSetImageCOI( timg, c+1 );     
            cvCopy( timg, tgray, 0 );  //依次将BGR通道送入tgray         
            for( int l = 0; l < N; l++ )     
            {         
                //不同阈值下二值化
                cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY );
    
                cvFindContours( gray, storage, &contours, sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );          
                while( contours )    
                { //多边形逼近             
                  result = cvApproxPoly( contours, sizeof(CvContour), storage,CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 ); 
                    //如果是凸多边形并且面积在范围内
                  if( result->total == SHAPE && fabs(cvContourArea(result,CV_WHOLE_SEQ)) > minarea  && fabs(cvContourArea(result,CV_WHOLE_SEQ)) < maxarea &&  cvCheckContourConvexity(result) )  
                    {               
                        s = 0;      
                        //判断每一条边
                        for( int i = 0; i < SHAPE+1 ; i++ )  
                        {                   
                            if( i >= 2 )           
                            {   //角度            
                                t = fabs(angle( (CvPoint*)cvGetSeqElem( result, i ),(CvPoint*)cvGetSeqElem( result, i-2 ),(CvPoint*)cvGetSeqElem( result, i-1 )));   
                                s = s > t ? s : t;     
                            }         
                        }   
                        //这里的S为直角判定条件 单位为角度
                        if( s > minangle && s < maxangle )                      
                            for( int i = 0; i < SHAPE; i++ )              
                                cvSeqPush( squares,(CvPoint*)cvGetSeqElem( result, i ));     
                    }                                      
                    contours = contours->h_next;      
                }   
            } 
        }
        cvReleaseImage( &gray );   
        cvReleaseImage( &pyr );  
        cvReleaseImage( &tgray );  
        cvReleaseImage( &timg );   
        return squares;
    }  
    //////////////////////////////////////////////////////////////////
    //函数功能:画出所有矩形
    //输入:   img 原图像
    //          squares 多边形序列
    //          wndname 窗口名称
    //输出:   图像中标记多边形
    //////////////////////////////////////////////////////////////////
    void drawSquares( IplImage* img, CvSeq* squares ,const char* wndname)
    {   
        CvSeqReader reader;   
        IplImage* cpy = cvCloneImage( img );   
        CvPoint pt[SHAPE];
        int i;       
        cvStartReadSeq( squares, &reader, 0 );     
        for( i = 0; i < squares->total; i += SHAPE )  
        {       
            CvPoint* rect = pt;    
            int count = SHAPE;      
            for (int j = 0; j < count; j++)
            {
                memcpy( pt+j , reader.ptr, squares->elem_size ); 
                CV_NEXT_SEQ_ELEM( squares->elem_size, reader ); 
            }
            cvPolyLine( cpy, &rect, &count, 1, 1, CV_RGB(rand()&255,rand()&255,rand()&255), 1, CV_AA, 0 );//彩色绘制
        }        
        cvShowImage( wndname, cpy );  
        cvReleaseImage( &cpy );
    }
    
    int main()
    {    
        CvCapture* capture = cvCreateCameraCapture(0);
        IplImage* img0 = 0;
        CvMemStorage* storage = 0;
        int c; 
        const char* wndname = "多边形检测"; //窗口名称
        storage = cvCreateMemStorage(0);    
        cvNamedWindow( wndname, 1 );    
        while (true)
        {
            img0 = cvQueryFrame(capture);      
            drawSquares( img0, findSquares4( img0, storage, 1000, 12000, 10, 180), wndname);
            cvClearMemStorage( storage );  //清空存储
            c = cvWaitKey(10); 
            if( c == 27 )       
            break;  
        }
    
        cvReleaseImage( &img0 );       
        cvClearMemStorage( storage );  
        cvDestroyWindow( wndname );   
        return 0;
    } 
    

    这里写图片描述

    展开全文
  • 圆的输出半径 用椭圆拟合二维点集 RotatedRect fitEllipse(InputArray points) //参数为输入的 std::vector 或 Mat 二维点集 逼近多边形曲线 用指定精度逼近多边形曲线 void approxPolyDP(InputArray curve, ...
  • 11、OpenCV多边形 —— cv.polylines()

    千次阅读 2020-09-29 13:30:16
    若为 False ,则画一条连接所有点的折线 color:多边形颜色 thickness:多边形线的粗细 lineType:多边形线的类型 shift:坐标精确到小数点后第几位 3、输出 img:画完多边形的输入图像 4、示例 代码 # 导入 OpenCV ...
  • 1.点多边形测试 (1)概念介绍 测试一个点是否在给定的多边形内部,边缘或者外部 (2)API介绍(cv::pointPolygonTest) pointPolygonTest(inputarray contour,//输入的轮廓 Point2f pt,//测试点 Bool ...
  • 使用opencv多边形拟合获取到的角点可能会存在很多个,对文字扭曲纠正,我本来是想找到4个角的坐标点,再使用透视变换纠正变形的文字,但自己研究,苦于没有找到好的方法,在此就自己写了个方法,还有一些问题存在...
  • @out:输出 @SAFELINE:负数为内缩, 正数为外扩。 需要注意算法本身并没有检测内缩多少后折线会自相交 */ void expand_polygon(const vector<Point> &pList, vector<Point> &out,float ...
  • opencv 多边形拟合

    2020-07-09 11:36:34
    函数 CV_EXPORTS_W void approxPolyDP( InputArray ...OutputArray approxCurve:表示输出多边形点集; double epsilon:拟合的多边形到原轮廓的最大距离,根据经验如果要拟合四边形,则该值为contour.size() / .
  • C++ OpenCV输出中文

    2020-11-02 09:00:00
    学更好的别人,做更好的自己。——《微卡智享》本文长度为2796字,预计阅读7分钟前言以前的文章《C++ OpenCV视频操作之图像输出文字》介绍了OpenCV中的putText函数可以输...
  • OpenCV 多边形逼近

    2019-10-01 17:38:35
    OutputArray Curve:输出的点集,当前点集是能最小包容指定点集的。画出来即是一个多边形;double epsilon:指定的精度,也即是原始曲线与近似曲线之间的最大距离;bool closed:若为true,则说明近似曲...
  • 摘自学习OpenCV3 当进行多边形或形状分析的时候,通常使用多边形逼近一个...输出存储在approxCurve数组中,参数epsilon是你要求逼近准确度,表示你允许在原多边形和最终拟合的多边形之间存在的最大偏差。最后一个参.
  • (opencv)任意多边形检测

    千次阅读 2020-02-08 12:54:24
    输出: 检测出的多边形角点 函数声明: vector<vector<Point>> polygonDetect(Mat&,double epsilon,int minAcreage); //多边形检测 调用: Mat matin=camera->read(); //视频流...
  • 当我们绘制一个多边形或者进行形状分析的时候,通常需要使用多边形逼近一个轮廓,使得顶点数目变少。有多种方法可以实现这个功能。opencv实现了其中的一种逼近算法。函数cvApproxPoly是该算法的一种实现,可以处理...
  • 介绍OpenCV自带的绘制多边形函数fillConvexPoly&&fillPoly
  • opencv多边形拟合曲线approxPolyDP()函数

    万次阅读 多人点赞 2019-01-08 14:51:57
    approxPolyDP()函数是opencv中对指定的点集进行多边形逼近的函数,其逼近的精度可通过参数设置。 对应的函数为: void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed); ...
  • Opencv C++ 绘制多边形/矩形/直线

    千次阅读 2020-06-05 10:30:50
    Opencv C++ 绘制多边形/矩形/直线 #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace std; ...
  • Python + OpenCV : 已知多边形轮廓的点坐标,自动识别多边形顶点坐标的算法 最近做工程,根据提供的目标物体的坐标(比如说分割结果输出的目标像素坐标),标其中遇到了RT说述问题,OpenCV并没有提供现成的函数,...
  • 基于python OpenCV多边形图像识别的实现

    千次阅读 多人点赞 2020-10-06 16:07:38
    首先说一下我的整体思路: ① 首先定义了一个识别器类型,封装了计算边长,识别形状和展示...④ 用之前创建的识别器实例对每个轮廓中的点进行多边形拟合,得到顶点的坐标的列表中去(class中28~32行代码) ⑤ 输出识别结
  • 在实际的应用中,常常需要将检测到的轮廓用多边形来表示,主要涉及到以下函数。 1、返回外部矩形边界:boundingRect()函数 此函数计算并返回指定点集最外面的矩形边界。 Rect boundingRect(InptArray points) ...
  • 相关知识 相关程序: 为了略去内部的一些程序...opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace std; using namespace cv; void contours_Callback(int, void*); Mat
  • 环境 win7 + vs2015 + Opencv2.4.13 对图像轮廓点进行多边形拟合 void approxPolyDP( InputArray curve,  OutputArray approxCurve,  double epsilon
  • opencv检测四边形/多边形

    万次阅读 2016-05-16 14:25:46
    如何用检测由直线构成的四边形(多边形)? 这个问题自己困扰了十来天, 查了相关的算法书 (a modern approach, algorithms and applications, computer and machine vision, Feature Extraction & Image Processing ),...
  • OpenCV里用polylines画多边形

    千次阅读 2019-12-23 11:48:10
    OpenCV进行图像处理时,有时候需要标记一些多边形物体,那么就需要使用函数polylines来画出来。先来看看这个函数polylines画出来的图,如下: 要深入地应用这个函数,我们得把这个函数的参数研究明白才可以...
  • 如何使用opencv 绘制轮廓边框最小包裹 多边形 圆形 矩形? 函数说明: Rect boundingRect(InputArray points) points:输入信息,可以为包含点的容器(vector)或是Mat。 返回包覆输入信息的最小正矩形。 RotatedRect ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,513
精华内容 1,005
关键字:

opencv输出多边形