轮廓_轮廓系数 - CSDN
精华内容
参与话题
  • Opencv 轮廓提取

    千次阅读 2019-01-27 23:38:06
    增强——使边界轮廓更加明显 检测——选出边缘点 方法一 Canny算法 特点:轮廓细腻 #include<opencv2\opencv.hpp> #include<opencv2\highgui\highgui.hpp> using namespace std;...

    边缘检测的一般步骤

    • 滤波——消除噪声
    • 增强——使边界轮廓更加明显
    • 检测——选出边缘点

    方法一

    Canny算法
    特点:轮廓细腻

    #include<opencv2\opencv.hpp>   
    #include<opencv2\highgui\highgui.hpp>
    
    using namespace std;
    using namespace cv;
    
    //边缘检测
    int main()
    {
    	Mat img = imread("1.jpg");
    	imshow("原始图", img);
    
    	Mat DstPic, edge, grayImage;
    
    	//创建与src同类型和同大小的矩阵
    	DstPic.create(img.size(), img.type());
    
    	//将原始图转化为灰度图
    	cvtColor(img, grayImage, COLOR_BGR2GRAY);
    
    	//先使用3*3内核来降噪
    	blur(grayImage, edge, Size(3, 3));
    
    	//运行canny算子
    	Canny(edge, edge, 3, 9, 3);
    
    	imshow("Canny算法轮廓提取效果", edge);
    
    	waitKey(0);
    }
    

    在这里插入图片描述

    方法二

    Sobel算法

    #include<opencv2\opencv.hpp>   
    #include<opencv2\highgui\highgui.hpp>
    
    using namespace std;
    using namespace cv;
    
    //边缘检测
    int main()
    {
    	Mat img = imread("1.jpg");
    
    	imshow("原始图", img);
    
    	Mat grad_x, grad_y;
    	Mat abs_grad_x, abs_grad_y, dst;
    
    	//求x方向梯度
    	Sobel(img, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
    	convertScaleAbs(grad_x, abs_grad_x);
    	imshow("x方向soble", abs_grad_x);
    
    	//求y方向梯度
    	Sobel(img, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
    	convertScaleAbs(grad_y, abs_grad_y);
    	imshow("y向soble", abs_grad_y);
    
    	//合并梯度
    	addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
    	imshow("Sobel算法轮廓提取效果", dst);
    
    	waitKey(0);
    }
    

    在这里插入图片描述

    方法三

    Laplacian算法

    #include<opencv2\opencv.hpp>   
    #include<opencv2\highgui\highgui.hpp>
    
    using namespace std;
    using namespace cv;
    
    //边缘检测
    int main()
    {
    	Mat img = imread("1.jpg");
    	imshow("原始图", img);
    	Mat gray, dst, abs_dst;
    	//高斯滤波消除噪声
    	GaussianBlur(img, img, Size(3, 3), 0, 0, BORDER_DEFAULT);
    	//转换为灰度图
    	cvtColor(img, gray, COLOR_RGB2GRAY);
    	//使用Laplace函数
    	//第三个参数:目标图像深度;第四个参数:滤波器孔径尺寸;第五个参数:比例因子;第六个参数:表示结果存入目标图
    	Laplacian(gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);
    	//计算绝对值,并将结果转为8位
    	convertScaleAbs(dst, abs_dst);
    	imshow("Laplace算法轮廓提取效果", abs_dst);
    	
    	waitKey(0);
    }
    

    在这里插入图片描述

    展开全文
  • OpenCV-目标轮廓提取

    2020-04-07 10:52:47
    原理:目标物体的轮廓实质是指一系列像素点构成,这些点构成了一个有序的点集。我们可以通过findContours函数将二值图像的边缘像素点分成多个轮廓,从而逐个提取目标外部轮廓,内部轮廓有待研究。 Python: import ...

    原理:目标物体的轮廓实质是指一系列像素点构成,这些点构成了一个有序的点集。我们可以通过findContours函数将二值图像的边缘像素点分成多个轮廓,从而逐个提取目标外部轮廓,内部轮廓有待研究。

    Python:

    import cv2 as cv
    import numpy as np
    
    
    if __name__=="__main__":
        img=cv.imread("D:/testimage/number.jpg")
        #img1=cv.imread("D:/testimage/sample.jpg")
        #灰度化+高斯滤波
        gray_dst = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
        blur_dst=cv.GaussianBlur(gray_dst,(3,3),0)
        #OTSU阈值分割
        ret,otsu_dst=cv.threshold(blur_dst,0,255,cv.THRESH_OTSU)
        cv.imshow("s", otsu_dst)
        #Canny算子提取边缘轮廓
        canny_dst=cv.Canny(otsu_dst,10,250)
        cv.imshow("s", canny_dst)
        #寻找二值图像轮廓点
        edge_points,h=cv.findContours(canny_dst,cv.RETR_EXTERNAL,
                                    cv.CHAIN_APPROX_SIMPLE)
        contours=edge_points
        #轮廓的数量
        k=len(edge_points)
        src=np.zeros(gray_dst.shape,np.uint8)
        for i in range(k):
            #画出轮廓
            cv.drawContours(src,contours,i,250,2)
            #最小外包圆
            circle=cv.minEnclosingCircle(contours[i])
            cv.circle(img,(int(circle[0][0]),int(circle[0][1])),int(circle[1]),(0,255,0),2)
            #绘制多边形
            approxCurve=cv.approxPolyDP(contours[i],0.3,True)
            t=approxCurve.shape[0]
            for i in range(t-1):
                cv.line(img,(approxCurve[i,0,0],approxCurve[i,0,1]),
                        (approxCurve[i+1,0,0],approxCurve[i+1,0,1]),(255,0,0),2)
                cv.line(img, (approxCurve[t-1, 0, 0], approxCurve[t-1, 0, 1]),
                        (approxCurve[0, 0, 0], approxCurve[0, 0, 1]),(255,0,0),2)
        cv.imshow("1",src)
        cv.imshow("2",img)
        cv.imwrite("D:/testimage/result-1.jpg", src)
        cv.imwrite("D:/testimage/result-2.jpg", img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    

    原图:
    在这里插入图片描述
    边缘提取:
    在这里插入图片描述
    目标轮廓:在这里插入图片描述

    展开全文
  • Opencv3笔记21——查找并绘制轮廓

    万次阅读 2018-08-11 11:31:01
    1. 寻找轮廓:findContours()函数 2. 绘制轮廓函数drawContours() 3. 基础示例程序:轮廓查找 4. 综合示例 一个轮廓一般对应一系列的点。也就是图像中的一条直线。 1. 寻找轮廓:findContours()函数 函数...

    一个轮廓一般对应一系列的点。也就是图像中的一条直线。

    1. 寻找轮廓:findContours()函数

    函数原型

    void findContours(InputOutputArray image,OutputArrayOfArrays contours,OutputArray hierarchy,int mode,int method, Point offset=Point)

    这里写图片描述

    • 第四个参数,int类型的mode,轮廓检索模式
      这里写图片描述

    • 第五个参数
      这里写图片描述

    2. 绘制轮廓函数drawContours()

    函数原型:

    void drawCountours(InputOutputArray image,InputArrayOfArrays contours, int contourIdx,const Scalar & color,int thickness = 1, int lineType = 8, InputArrayhierarchy = noArray(),int maxLevel = INT_MAX,Point offset = Point())

    这里写图片描述

    这里写图片描述

    3. 基础示例程序:轮廓查找

    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <vector>
    
    using namespace cv;
    using namespace std;
    
    int main()
    {
        //载入原始图
        Mat srcImage = imread("1.jpg", 0);
    
        //显示原始图
        imshow("原始图", srcImage);
    
        //初始化结果图
        Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
    
        //阈值化
        srcImage = srcImage > 119;
        imshow("阈值化后的原始图", srcImage);
    
        //定义轮廓和层次结构
        vector<vector<Point> >contours;
        vector<Vec4i> hierarchy;
        //查找轮廓
    
        findContours(srcImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
    
        //遍历所有的顶层的轮廓,随机颜色绘制每个连接组件颜色
    
        int index = 0;
    
        for (; index >= 0; index = hierarchy[index][0])
        {
            Scalar color(rand() & 255, rand() & 255, rand() & 255);
            drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
        }
    
        imshow("轮廓图", dstImage);
        waitKey(0);
        return 0;
    }

    这里写图片描述

    这里写图片描述

    这里写图片描述

    4. 综合示例

    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    
    //定义宏部分
    #define WINDOW_NAME1 "【原始图窗口】"
    #define WINDOW_NAME2 "【轮廓图】"
    
    //定义全局变量
    Mat g_srcImage;
    Mat g_grayImage;
    int g_nThresh = 80;
    int g_nThresh_max = 255;
    RNG g_rng(12345);
    Mat g_cannyMat_output;
    vector<vector<Point> > g_vContours;
    vector<Vec4i> g_vHierarchy;
    
    //全局函数
    void on_ThreshChange(int, void *);
    
    int main()
    {
        //改变console字体颜色
        system("color 1F");
    
        //加载源图像
        g_srcImage = imread("1.jpg", 1);
        if (!g_srcImage.data)
        {
            printf("读取图片错误~!\n");
            return false;
        }
    
        //转成灰度并模糊降噪
        cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
        blur(g_grayImage, g_grayImage, Size(3, 3));
    
        //创建窗口
        namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
        imshow(WINDOW_NAME1, g_srcImage);
    
        //创建轨迹条
        createTrackbar("canny 阈值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange);
        on_ThreshChange(0, 0);
        waitKey(0);
        return 0;
    }
    
    //on_ThreshChange()函数
    
    void on_ThreshChange(int, void *)
    {
        //调用canny算子检测边缘
        Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);
    
        //寻找轮廓
        findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
        Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
        for (int i = 0; i < g_vContours.size(); i++)
        {
            Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));
            drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
        }
        imshow(WINDOW_NAME2, drawing);
    }
    

    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述

    这里写图片描述

    展开全文
  • 有时需要对已有的图像进行处理,使其更清晰或更规则,轮廓检测可以达到这个目的。先介绍几个相关函数: 1.findContours函数 findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArray ...

    有时需要对已有的图像进行处理,使其更清晰或更规则,轮廓检测可以达到这个目的。先介绍几个相关函数:
    1.findContours函数

    findContours( InputOutputArray image, OutputArrayOfArrays contours,
                                  OutputArray hierarchy, int mode,
                                  int method, Point offset=Point());
    
    

    第一个参数:image,单通道图像矩阵,可以是灰度图,但更常用的是二值图像
    第二个参数:contours,定义为“vector<vector> contours”,是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。
    第三个参数:hierarchy,表示层数,定义为“vector hierarchy”, 定义了一个“向量内每一个元素包含了4个int型变量”的向量。
    第四个参数:int型的mode,定义轮廓的检索模式:
    取值一:CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
    取值二:CV_RETR_LIST 检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关 系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓, 所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到
    取值三:CV_RETR_CCOMP 检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围 内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层
    取值四:CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
    第五个参数:int型的method,定义轮廓的近似方法:
    取值一:CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内
    取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留

    2.drawContours函数

    void drawContours(InputOutputArray image, 
                      InputArrayOfArrays contours, int contourIdx, const Scalar& color,
                      int thickness=1, int lineType=8, InputArray hierarchy=noArray(),
                      int maxLevel=INT_MAX, Point offset=Point() )
    
    

    其中第一个参数image表示目标图像,

    第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成,

    第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,

    第四个参数color为轮廓的颜色,

    第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,

    第六个参数lineType为线型,

    第七个参数为轮廓结构信息,

    第八个参数为maxLevel

    3.approxPolyDP函数
    它是用来进行多边形逼近,可以将不规则的图形逼近成规则图形,方便处理

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

    InputArray curve:一般是由图像的轮廓点组成的点集

    OutputArray approxCurve:表示输出的多边形点集

    double epsilon:主要表示输出的精度,就是另个轮廓点之间最大距离数

    bool closed:表示输出的多边形是否封闭,封闭可用true表示

    下面举个例子来说明这些函数的用途,以便理解:

    #include <opencv2\core\core.hpp>
    #include <opencv2\highgui\highgui.hpp>  //opencv申明
    #include <opencv2\imgproc\imgproc.hpp>
    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include "highgui.h"
    
    using namespace std;
    using namespace cv;
    int dis,dis1,dis2,dis3,dis4,dis5,dis6;
    
    int length(Point a,Point b)//两点间距离求边长
    {
    	int d = (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    	dis = sqrt(d);
    	return dis;
    	 
    }
    int main()
    {
    	int sum = 0;
    	Mat t_image,f_image,src;
    	vector<Vec4i> hierarchy;
    	vector<vector<Point>> contours;
    	Mat image = imread("D:\\program\\51.png",0);//读入模板图
    	Mat dstImg(image.size(), CV_8UC3, Scalar::all(0));//纯黑图像
    
        int u1 = image.rows;//阈值化处理
    	int u2 = image.cols;
    	for (int i = 0; i < image.rows; i++)
    	{
    		for (int j = 0; j < image.cols; j++)
    		{
    			
    	        sum = sum + image.at<uchar>(i, j);
    		}
    	}
    	int u = u1*u2;
    	int average = (int)sum/u*2;
    	threshold(image, src, average, 255, CV_THRESH_BINARY); 
    	Canny(src,t_image,50,50);
    	imshow("阈值分割图",t_image);
    	waitKey(0);
    
    
    	findContours(t_image, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));//得到原图像轮廓点集
    	drawContours(dstImg, contours,-1, Scalar(0, 255, 255), 2, 8);//根据点集画出图像轮廓
    	imshow("轮廓图",dstImg);
    	waitKey(0);
    	vector<vector<Point>> contours_poly(contours.size());//用于存放折线点集
    	
    	
    	for (int i = 0; i<contours.size(); i++)
        {
            approxPolyDP(Mat(contours[i]), contours_poly[i], 15, true);//根据原图像点集得到逼近的图像点集
            drawContours(dstImg, contours_poly, i, Scalar(0, 255, 255), 2, 8);  //绘制逼近图形
    		/*for(int j = 0;j<contours_poly[i].size;j++)
    		{
    			Point pta = contours_poly[i][j];
    			Point pta = contours_poly[i][j+1];
    		}*/
    		    Point pta = contours_poly[i][0];//提出逼近图像点集计算边长
    		    Point ptb = contours_poly[i][1];
    		    Point ptc = contours_poly[i][2];
    		    Point ptd = contours_poly[i][3];
    			//Point pte = contours_poly[i][4];
    			//Point ptf = contours_poly[i][5];
    			dis1 = length(pta,ptb);
    	        dis2 = length(ptb,ptc);
    	        dis3 = length(ptc,ptd);
    	        dis4 = length(ptd,pta);
    			
        }
    	cout<<"各边长度为:"<<dis1<<"、"<<dis2<<"、"<<dis3<<"、"<<dis4<<endl;
    	imshow("轮廓图",dstImg);
    	waitKey(0);
    	
    }
    
    

    在这里插入图片描述

    展开全文
  • 轮廓

    2018-03-11 09:29:10
    1、轮廓提取 对于二值图像,就是掏空内部点:如果原图中有一点为黑,且它的8个相邻点都是黑(该点即为内部点),则将该点删除。 形态学方法:用3X3的结构元素对原图像进行腐蚀,再用原图减去腐蚀后的图像,即得到...
  • OpenCV图像的轮廓

    千次阅读 2018-10-31 13:01:46
    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow也欢迎大家转载本...分享知识,造福人民,实现我们中华民族伟大复兴!&nbsp;&nbsp;&nbsp;... 查找轮廓轮廓到底是什么
  • OpenCV学习笔记(7)—轮廓

    千次阅读 2013-05-15 09:52:33
    查找轮廓 轮廓到底是什么?一个轮廓一般对应一系列的点,也就是图像中的一条曲线.表示的方法可能根据不同情况而有所不同.有多重方法可以表示曲线.在openCV中一般用序列来存储轮廓信息.序列中的每一个元素是曲线中一个...
  • 轮廓 轮廓即是以某种方式表示图像中的曲线的点的列表。这种表示可以根据实际的情形不同而不同。表示一条曲线的方式有很多种。OpenCV中,轮廓是由STL风格的vector<>模板对象表示的,其中vector中的每个元素都...
  • (openCV 十九)轮廓Contours形状拟合

    千次阅读 2019-06-27 15:37:21
    什么是轮廓轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同 的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。 • 为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行...
  • 【OpenCV + Python】轮廓

    千次阅读 2019-06-30 21:44:16
    轮廓查找: • 为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理或者Canny 边界检测。 • 查找轮廓的函数会修改原始图像。如果你在找到轮廓之后还想使用原始图像的话,你应该将原始图像存储到...
  • OpenCV 内轮廓与外轮廓说明

    万次阅读 2017-03-18 18:31:36
    opencv提供了findContours函数查找轮廓,函数原型为CV_EXPORTS_W void findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point()...
  • opencv中轮廓内部的像素点怎么提取

    万次阅读 2016-05-04 19:13:54
    opencv轮廓内面积的提取
  • 轮廓提取后,它是用关键点组成的,下面提取出这些关键点。 1.先输出所有关键点的个数couttotal 2.for(int i=0;itotal;++i)  {  CvPoint* p = CV_GET_SEQ_ELEM(CvPoint,contour,i);  cout  }
  • 关于“轮廓检测”和“边缘检测”这两个自己也弄的不是特别清楚,可能确实比较相似吧。下面简单说一下自己的看法。 区别: 边缘检测主要是通过一些手段检测数字图像中明暗变化剧烈(即梯度变化比较大)像素点,偏向...
  • PS提取图形轮廓

    万次阅读 2017-07-09 14:37:23
    需要做图形轮廓相关的程序,所以记录一下其中的一些处理过程备忘,和程序没有太大关系。 打开文件启动PS软件,从文件——打开中,打开JPG格式的图片,如下: 查找边缘 滤镜——风格化——查找边缘 为了获得更...
  • OpenCV中findcontours函数hierarchy轮廓层级详解

    万次阅读 多人点赞 2018-07-31 08:47:40
    最近在查阅OpenCV轮廓处理函数方面时,我发现有部分文章对findcontours函数中轮廓层级提取的描述有错误,特写一篇有关轮廓提取方面的文章(仅仅介绍容易出错的hierarchy层级轮廓)。 函数原型为:findContours...
  • 使用Matlab对二值图像进行轮廓提取

    万次阅读 2015-12-26 10:39:25
    参考资料 [1]
  • OpenCV图象孔洞内轮廓填充

    万次阅读 2013-06-03 11:39:05
    图像内轮廓填充通常称为孔洞填充,主要用于目标提取。不带任何条件的内轮廓填充,在目标密度很大时,可能导致错误填充。一种典型情况,当多个目标粘连,并 且形成环状时,简单的内轮廓填充会将环状内部背景部分误...
  • findContours函数参数详解

    万次阅读 多人点赞 2018-04-03 21:54:27
    注: 这篇文章用的OpenCV版本是2.4.10, 3以上的OpenCV版本相关函数可能有改动Opencv中通过使用findContours函数,简单几个的步骤就可以检测出物体的轮廓,很方便。这些准备继续探讨一下findContours方法中各参数的...
  • 轮廓检测(python+opencv)

    千次阅读 2018-05-27 17:11:42
    轮廓可以理解为图像中具有相同颜色或密度的位于边界的连续点的集合,轮廓是形状分析和对象识别的有利工具。 在python-OpenCV中,我们常用findContours函数来计算轮廓,每个独立的轮廓都是以Numpy array的点坐标的...
1 2 3 4 5 ... 20
收藏数 96,762
精华内容 38,704
关键字:

轮廓