图片解析:

原图:

code:

#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <opencv\cxcore.h>
#include <stdlib.h>
#include <stdio.h> int main(int argc, char* argv[]){ #if 1 int i, j; CvMemStorage* storage = cvCreateMemStorage(0);
//以单通道方式加载图像
IplImage* img = cvLoadImage("C:\\Users\\zxl\\Desktop\\0.png",CV_LOAD_IMAGE_GRAYSCALE);
//常见一个等大小的3通道图像 (作为备份)
IplImage* imgColor = cvCreateImage(cvGetSize(img),8,3);
//用来显示轮廓的
IplImage* contoursImage = cvCreateImage(cvSize(img->width,img->height),8,1); CvSeq* contours = 0 , *contoursTemp=0;
cvZero(contoursImage); //对图像进行二值化
cvThreshold(img,img,100,255,CV_THRESH_BINARY); //img的备份
cvCvtColor(img,imgColor,CV_GRAY2BGR); // 提取图像img的轮廓信息函数 contours指向第一个轮廓 将轮廓存放在CvMemStorage类型的变量storage里面
//&contours =>表示指针 指向能够提取的第一个轮廓
//CV_RETR_CCOMP =>表示轮廓的排列方式 有4种
//-------------------------------------
//CV_RETR_EXTERNAL 只返回最外面的轮廓
//first=c0
//CV_RETR_CCOMP 把外轮廓用双向链表的方式存放,有顺序 <从里到外><从右到左>
//frist=c01001 <-> c01000 <-> c010 <-> c000 <-> c0
// | | |
// h0100 h0000 h01 <-> h00
//CV_RETR_LIST 所有的轮廓(无分内外轮廓)通过1个链表的方式存储,<从里到外><从右到左>
//first=c01001 <-> c01000 <-> h0100 <-> h0000 <-> c010 <-> c000 <-> h01 <-> h00 <-> c0
//
//
//CV_RETR_TREE 按照树形结构存储,
//first = c0
// |
// h00 <-> h01
// | |
// c000 c010
// | |
// h0000 c01000 <-> c01001
//-------------------------------------
//CV_CHAIN_APPROX_NONE=> 轮廓显示是坐标的形式还是点的形式
//提取轮廓后源图像会发生变化 所以需要用到开始生命的备份机制 /*
//备份机制检查原图
cvNamedWindow( "1");
cvShowImage( "1", img );
*/ int total = cvFindContours( img, storage, &contours, sizeof(CvContour),
CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0) ); /*
//备份机制检查提取后
cvNamedWindow( "2");
cvShowImage( "2", img );
cvWaitKey(0);
*/ //提取指针所指的地方
contoursTemp = contours ; int count=0; //对轮廓进行循环
//h_next 表示水平的方向上轮廓链接
//v_next 表示垂直方向上的轮廓链接
for(;contoursTemp!=0 ; contoursTemp=contoursTemp->h_next){ //通过这个循环访问每一个轮廓
//提取外轮廓 上的所以坐标点
for( i=0; i<contoursTemp->total; i++) { //通过这个循环 得到坐标
CvPoint * pt = (CvPoint*)cvGetSeqElem(contoursTemp, i); // 读出第i个点。
//轮廓窗口让其显示为白色
cvSetReal2D(contoursImage , pt->y , pt->x , 255.0);
//在原窗口让其显示为红色
cvSet2D(imgColor,pt->y,pt->x,cvScalar(0,0,255,0));
}
count++; //提取内轮廓上的所以坐标点
CvSeq* InterCon = contoursTemp->v_next; for(;InterCon!=0;InterCon=InterCon->h_next){
for(i=0;i<InterCon->total;i++) {
CvPoint * pt = (CvPoint*)cvGetSeqElem(InterCon, i); // 读出第i个点。 cvSetReal2D(contoursImage , pt->y , pt->x , 255.0);
cvSet2D(imgColor,pt->y,pt->x,cvScalar(0,255,0,0));
}
}
} cvNamedWindow( "image", 1 );
cvShowImage( "image", imgColor ); cvNamedWindow( "contours");
cvShowImage("contours",contoursImage); cvWaitKey(0); cvReleaseMemStorage( &storage );
cvReleaseImage( &img );
cvReleaseImage(&contoursImage);
cvReleaseImage(&imgColor); #endif return 0;
}

效果:

opencv 图像轮廓的更多相关文章

  1. OpenCV图像轮廓检测

    轮廓检测: 轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点.那么就可以将中间的那一点去掉. 一.关键函数1.1  cvFindContours函数功能:对图像进行轮廓检测,这个函数将 ...

  2. opencv 6 图像轮廓与图像分割修复 3 图像的矩,分水岭,图像修补

    图像的矩 矩的计算:moments()函数 计算轮廓面积:contourArea()函数 #include "opencv2/highgui/highgui.hpp" #inclu ...

  3. OpenCV计算机视觉学习(8)——图像轮廓处理(轮廓绘制,轮廓检索,轮廓填充,轮廓近似)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...

  4. OpenCV笔记(3)(Canny边缘检测、高斯金字塔、拉普拉斯金字塔、图像轮廓、模板匹配)

    一.Canny边缘检测 Canny边缘检测是一系列方法综合的结果.其中主要包含以下步骤: 1.使用高斯滤波器,平滑图像,滤除噪声. 2.计算图像中每个像素点的梯度强度和方向. 3.应用非极大值抑制(N ...

  5. 【python+opencv】轮廓发现

    python+opencv---轮廓发现 轮廓发现---是基于图像边缘提取的基础寻找对象轮廓的方法, 所有边缘提取的阈值选定会影响最终轮廓发现的结果. 介绍两种API使用: -cv.findConto ...

  6. OpenCV—Python 轮廓检测 绘出矩形框(findContours\ boundingRect\rectangle

    千万注意opencv的轮廓检测和边缘检测是两码事 本文链接:https://blog.csdn.net/wsp_1138886114/article/details/82945328 1 获取轮廓 O ...

  7. OpenCV3入门(十)图像轮廓

    1.图像轮廓 1.1图像轮廓与API函数 轮廓是一系列相连的点组成的曲线,代表了物体的基本外形,相对于边缘,轮廓是连续的,边缘并不全部连续.一般地,获取图像轮廓要经过下面几个步骤: 1)     读取 ...

  8. OpenCV图像处理中“投影技术”的使用

           本文区分"问题引出"."概念抽象"."算法实现"三个部分由表及里具体讲解OpenCV图像处理中"投影技术" ...

  9. opencv——图像直方图与反向投影

    引言 在图像处理中,对于直方图这个概念,肯定不会陌生.但是其原理真的可以信手拈来吗? 本文篇幅有点长,在此列个目录,大家可以跳着看: 分析图像直方图的概念,以及opencv函数calcHist()对于 ...

随机推荐

  1. 李洪强iOS开发之【零基础学习iOS开发】【02-C语言】07-基本数据类型

    C语言有丰富的数据类型,因此它很适合用来编写数据库,如DB2.Oracle等大型数据库都是C语言写的.其中,提供了4种最常用的基本数据类型:char.int.float.double,使用这些数据类型 ...

  2. Winform 数据验证

    http://blog.scosby.com/post/2010/02/11/Validation-in-Windows-Forms.aspx 总结:1. CancelEventArgs e ,调用e ...

  3. fd_set 用法

    http://www.cnblogs.com/wolflion/archive/2011/07/13/2539137.html select()函数主要是建立在fd_set类型的基础上的.fd_set ...

  4. Windbg:如何给字符串下条件断点

    因为Windgb支持MASM语法,字符串的比较方法有$scmp和$sicmp.用法和c中的字符串比较方法一致.在需要比较字符串成员变量的时候,遇到了点问题.因为字符串成员变量无法直接获取字符串内容.p ...

  5. Android 签名(5)用命令签名和用IDE签名

    1,用命令签名 无论用哪个 IDE 开发,最终只是用了 keytool 和 jarsigner 这两个 Java 工具来完成签名任务(在 jdk 的 bin 目录下).其中 keytool 用来生成 ...

  6. 摄像头(4)用Camera和SurfaceView自定义拍照程序

    定制拍照程序的基本步骤 1,打开照相机:Camera.open 这是独占方式打开的 2,创建SurfaceView对象 多缓冲,多线程view 3,添加回调事件监听器(SurfaceHolder.ad ...

  7. 命令行下玩VC

    说明:(1)转载请注明出处:http://www.cnblogs.com/opangle/p/4298155.html (2)以下以VS2013为例,并假设VC安装路径为%VC_INSTALL_PAT ...

  8. 如何在 OS X Yosemite 中安装 Java

    如果你的 Mac 纯净的安装了 OS X Yosemite 的话,其中是不会包含 Java 的,如果你的 Mac 需要安装 Java 环境的话,可以通过下面介绍的两种方法来实现.通过手动安装最新版 J ...

  9. [.NET WebAPI系列02] WebAPI 中的HTTP通信

    [前言] 本节用于承上启下,通过第一节了解的WebAPI的基本语法,Controller CRUD方法的基本格式: 但很多场合,第一节中的Web API Controller方法返回的信息 过于简单, ...

  10. 《C#并行编程高级教程》第9章 异步编程模型 笔记

    这个章节我个人感觉意义不大,使用现有的APM(异步编程模型)和EAP(基于时间的异步模型)就很够用了,针对WPF和WinForm其实还有一些专门用于UI更新的类. 但是出于完整性,还是将一下怎么使用. ...