Opencv实现轮廓提取功能

轮廓:一个轮廓代表一系列的点(像素),这一系列的点构成一个有序的点集,所以可以把一个轮廓理解为一个有序的点集。

在opencv中,提供了一个函数返回一个有序的点集或者有序的点集的集合(指多个有序的点集),函数findContour是从二值图像中来计算轮廓的,一般使用Canny()函数处理后的图像,因为这样的图像含有边缘像素。

寻找轮廓的API函数:

findContours(image,vector<vector<Point>> contours,vector<Vec4i>hierarchy,int mode,int method,Point offset = Point(0,0));

参数解释:

(1)image:单通道图像矩阵,一般是经过canny处理后的二值图像;

(2)contours:vector<vector<Point>>类型,是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。有多少轮廓,向量contours就有多少元素;

(3)hierarchy:vector<Vec4i> 类型, 即容器内每一个元素都是一个包含了4个int型变量的向量,向量内每个元素保存了一个包含4个int整型的数组。向量hiararchy内的元素和轮廓向量contours内的元素是一一对应的,向量的容量相同。hierarchy向量内每一个元素的4个int型变量——hierarchy[i][0] ~hierarchy[i][3],分别表示第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓或内嵌轮廓的话,则hierarchy[i][0] ~hierarchy[i][3]的相应位被设置为默认值-1;

(4)mode:int类型的,定义轮廓的检索模式:

  • CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略;
  • CV_RETR_LIST   检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到;
  • CV_RETR_CCOMP  检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层;
  • CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。

(5)method:int类型,定义轮廓的近似方法:

  • CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内;
  • CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留;
  • CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法;

(6) Point:偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,一般不偏移取Point(0,0)。

画轮廓的API函数:

drawContours(Outputimage,contours,hierarchy,int contourIdx,color,int thickness ,int lineType,hierarchy = noArray(),int maxLevel = INT_MAX,Point offset = Point(0,0))
参数解释:

(1)outputimage: 将轮廓画在该图上;
    (2)contours:前面寻找到的轮廓;
    (3)contourIdx:是一个索引,代表绘制contours中的第几个轮廓;
    (4) color:颜色;
    (5)thickness: 线宽;
    (6)lineType: 线型;
    (7)hierarchy:可选层次信息结构,这里面是findContours所的到的基于Contours的层级信息;
    (8)maxLevel: 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓;

(9)offset:照给出的偏移量移动每一个轮廓点坐标.当轮廓是从某些感兴趣区域(ROI)中提取的然后需要在运算中考虑ROI偏移量时,将会用到这个参数。

以上定义摘自该篇博客:OpenCV实现轮廓的发现。

#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int value = 50;
Mat src, dst, canny_img;
void callback(int, void*);
int main(int arc, char** argv)
{
 src = imread("2.jpg");
 namedWindow("src",CV_WINDOW_AUTOSIZE);
 imshow("src", src);
 cvtColor(src, src, CV_BGR2GRAY);

 namedWindow("output", CV_WINDOW_AUTOSIZE);
 createTrackbar("threshold", "output", &value, 255, callback);
 callback(0, 0);
 waitKey(0);
 return 0;
}
void callback(int, void*) {
 Canny(src, canny_img, value, 2 * value);
 imshow("canny", canny_img);
 vector<vector<Point>>contours;
 vector<Vec4i>hierarchy;
 findContours(canny_img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE,Point(0,0));

 dst = Mat::zeros(src.size(), CV_8UC3);
 RNG rng(1);
 for (int i = 0; i < contours.size(); i++) {
 Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
 drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0, 0));
 }
 imshow("output", dst);
} 

运行结果如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • opencv提取外部轮廓并在外部加矩形框

    这段时间一直在用opencv搞图像处理的问题,发现虽然可调用的函数多,但是直接找相应代码还是很困难,就行寻找连通域,并在连通域外侧加框,对于习惯使用Mat矩形操作的我,真心感觉代码少之又少,为防止以后自己还会用到,特在此记录一下. 要对下面的图像进行字符的边缘检测. 程序中具体的步骤为: (1)灰度化.二值化 (2)图像膨胀 (3)检测膨胀图像的边缘并叫外矩形框 实现代码如下: #include "stdafx.h" #include "stdio.h" #incl

  • Opencv处理图像之轮廓提取

    本文实例为大家分享了Opencv处理图像之轮廓提取,使用cvfindContours对图像进行轮廓检测,供大家参考,具体内容如下 #include<iostream> #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> int main() { IplImage* img = cvLoadImage("E:\\test.bmp",0); IplImage* img

  • Opencv提取连通区域轮廓的方法

    本文实例为大家分享了Opencv提取连通区域轮廓的具体代码,供大家参考,具体内容如下 在进行图像分割后,可能需要对感兴趣的目标区域进行提取,比较常用的方法是计算轮廓. 通过轮廓可以获得目标的一些信息: (1)目标位置 (2)目标大小(即面积) (3)目标形状(轮廓矩) 当然,轮廓不一定代表希望目标区域,阈值分割时可能造成一部分信息丢失,因此可以计算轮廓的质心坐标,再进行漫水填充. 程序中有寻找质心+填充,但效果不好,因此就不放填充后的图了. 实验结果: #include "opencv2/img

  • python-opencv在有噪音的情况下提取图像的轮廓实例

    对于一般的图像提取轮廓,介绍了一个很好的方法,但是对于有噪声的图像,并不能很好地捕获到目标物体. 比如对于我的鼠标,提取的轮廓效果并不好,因为噪声很多: 所以本文增加了去掉噪声的部分. 首先加载原始图像,并显示图像 img = cv2.imread("temp.jpg") #载入图像 h, w = img.shape[:2] #获取图像的高和宽 cv2.imshow("Origin", img) 然后进行低通滤波处理,进行降噪 blured = cv2.blur(i

  • C语言实现opencv提取直线、轮廓及ROI实例详解

    一.Canny检测轮廓 在上一篇文章中有提到sobel边缘检测,并重写了soble的C++代码让其与matlab中算法效果一致,而soble边缘检测是基于单一阈值的,我们不能兼顾到低阈值的丰富边缘和高阈值时的边缘缺失这两个问题.而canny算子则很好的弥补了这一不足,从目前看来,canny边缘检测在做图像轮廓提取方面是最优秀的边缘检测算法. canny边缘检测采用双阈值值法,高阈值用来检测图像中重要的.显著的线条.轮廓等,而低阈值用来保证不丢失细节部分,低阈值检测出来的边缘更丰富,但是很多边缘并

  • Opencv实现轮廓提取功能

    轮廓:一个轮廓代表一系列的点(像素),这一系列的点构成一个有序的点集,所以可以把一个轮廓理解为一个有序的点集. 在opencv中,提供了一个函数返回一个有序的点集或者有序的点集的集合(指多个有序的点集),函数findContour是从二值图像中来计算轮廓的,一般使用Canny()函数处理后的图像,因为这样的图像含有边缘像素. 寻找轮廓的API函数: findContours(image,vector<vector<Point>> contours,vector<Vec4i&g

  • OpenCV图像轮廓提取的实现

    目录 前言 提取傅里叶变换的高频信息 通过蚁群算法进行图片轮廓提取 Canny边缘检测   使用cuda加速提取轮廓 前言 常用的轮廓提取算法有:Canny.阈值分割.提取傅里叶变换的高频信息,还有别具一格的蚁群算法,当然比较常见的作法是使用阈值分割+边缘查找,在OpenCV里是threshold和findContours两个函数的组合使用,和Canny. 轮廓提取的算法很多,而其目的都是为了找到图像中灰阶差比较大的位置.而所谓亚像素提取,则是使用了插值算法,以找出灰阶差最大的位置. 提取傅里叶

  • python+opencv实现车牌定位功能(实例代码)

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验三,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验三. 由于时间紧张,代码没有进行任何优化,实验算法仅供参考. 实验要求 对给定的车牌进行车牌识别 实验代码 代码首先贴在这里,仅供参考 源代码 实验代码如下: import cv2 import numpy as np def lpr(filename): img = cv2.imread(filename) # 预处理,包括灰度处理,高斯

  • C++ OpenCV实现银行卡号识别功能

    目录 前言 一.获取模板图像 1.1 功能效果 1.2 功能源码 二.银行卡号定位 2.1 将银行卡号切割成四块 2.2 字符切割 三.字符识别 3.1.读取文件 3.2.字符匹配 3.3.功能源码 四.效果显示 4.1 功能源码 4.2 效果显示 五.源码 5.1 hpp文件 5.2 cpp文件 5.3 main文件 总结 前言 本文将使用OpenCV C++ 进行银行卡号识别.主要步骤可以细分为: 1. 获取模板图像 2.银行卡号区域定位 3.字符切割 4.模板匹配 5.效果显示 接下来就具

  • python中的opencv 图像分割与提取

    目录 图像分割与提取 用分水岭算法实现图像分割与提取 算法原理 相关函数介绍 分水岭算法图像分割实例 交互式前景提取 图像分割与提取 图像中将前景对象作为目标图像分割或者提取出来.对背景本身并无兴趣分水岭算法及GrabCut算法对图像进行分割及提取. 用分水岭算法实现图像分割与提取 分水岭算法将图像形象地比喻为地理学上的地形表面,实现图像分割,该算法非常有效. 算法原理 任何一幅灰度图像,都可以被看作是地理学上的地形表面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山谷. 左图是原

  • opencv 图像轮廓的实现示例

    图像轮廓 Contours:轮廓 轮廓是将没有连着一起的边缘连着一起. 边缘检测检测出边缘,边缘有些未连接在一起. 注意问题 1.对象为二值图像,首先进行阈值分割或者边缘检测. 2.查找轮廓需要更改原始图像,通常使用原始图像的一份进行拷贝. 3.在opencv里,是从黑色背景里找白色.因此对象必须是白色,背景为黑色. 方法 cv2.findContours() cv2.drawContours() 通过cv2.findContours() 查找轮廓在哪里,再通过 cv2.drawContours

  • opencv实现轮廓高斯滤波平滑

    本文实例为大家分享了opencv实现轮廓高斯滤波平滑的具体代码,供大家参考,具体内容如下 一个小测试的题目: 在图像上点选,找到与点选处相邻的颜色相近的点集合,对该点集合提取轮廓,对该点集合轮廓平滑处理,显示处理结果. #include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; //************************************ //

  • C++ OpenCV实现图像去水印功能

    目录 前言 一.水印定位 二.图像修复 三.效果显示 四.源码 总结 前言 本文将使用OpenCV C++ 进行简单图像水印去除.我们在网上download图片时,经常因为版权问题有水印.本案例通过编写算法进行简单水印去除. 一.水印定位 如图所示,图像左下角.右下角有水印.第一步,我们首先得定位水印所在位置. Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); //图像二值化,筛选出白色区域部分 Mat thresh; threshold(gray,

  • python计算机视觉opencv矩形轮廓顶点位置确定

    目录 一.问题的引入 二.问题的解决方法 方法一: 方法二 三.一些实现代码 一.问题的引入 opencv在图像处理方面有着非常强大的功能,当我们需要使用opencv进行一些图像的矫正工作时,我们通常需要找到原图的一些关键点,然后计算变换后的图像坐标,最后通过仿射变换或者透视变换获得自己想要的矫正图像,比如将一张拍歪了的纸进行矫正,我们的首要任务就是找到原图的一些关键点,通常的做法就是找纸张的4个顶点. 二.问题的解决方法 第一步我们肯定要找到纸张相应的矩形轮廓,这里可以二值化再找,也可以使用一

随机推荐