好久没有更新了,原谅自己放了个假最近又在赶进度,所以。。。更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号。。。加油加油!

在二值图像中寻找轮廓

void cv::findContours    (    InputOutputArray     image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
  • image: 输入图像,需为8位单通道图像,图像非0像素视为1。 可以用compare(), imrange(), threshold(), adaptivethreshold(), canny()等函数创建,注意:此函数会在提取图像轮廓的同时修改图像内容。
    • If mode equals to RETR_CCOMP or RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1).
  • contours: 检测到的轮廓,每个轮廓存储为一个点向量,即用point类型的vector,例如可为类型vector<vector<Point> >。
  • hierarchy: 可选的输出向量,包含图像的拓扑信息。 每个轮廓contours[i],
    • hierarchy[i][0] , 后一个轮廓,
    • hierarchy[i][1] , 前一个轮廓,
    • hierarchy[i][2] , 父轮廓,
    • hierarchy[i][3], 内嵌轮廓的索引编号。
    • 如果没有对应项,hierarchy[i]中的对应项设为负数。
  • mode: 检索模式,可选模式包括
    • RETR_EXTERNAL: 只监测最外层轮扩。hierarchy[i][2] = hierarchy[i][3] = -1
    • RETR_LIST: 提取所有轮廓,并放置在list中。检测的轮廓不建立等级关系。
    • RETR_CCOMP: 提取所有轮廓,并将其组织为双层结构,顶层为联通域的外围边界,次层为空的内层边界。
    • RETR_TREE: 提取所有轮廓,并重新建立网状的轮廓结构。
  • method: 轮廓的近似办法,包括
    • CHAIN_APPROX_NONE: 获取每个轮廓的每个像素,相邻两点像素位置差不超过1,max(abs(x1-x2),abs(y1-y2)) == 1
    • CHAIN_APPROX_SIMPLE: 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标
    • CHAIN_APPROX_TC89_LI /CHAIN_APPROX_TC89_KCOS: 使用Teh-Chinl链逼近算法中的一个
      • [135] C-H Teh and Roland T. Chin. On the detection of dominant points on digital curves. Pattern Analysis and Machine Intelligence, IEEE Transactions on, 11(8):859–872, 1989.
  • offSet: 每个轮廓点的可选偏移量,默认Point(), 当ROI图像中找出的轮廓需要在整个图中进行分析时,可利用这个参数。

绘制轮廓

void cv::drawContours    (    InputOutputArray     image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar & color,
int thickness = ,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
)
  • image: 目标图像
  • contours: 输入轮廓,每个轮廓存储为一个点向量
  • contourIdx: 需要绘制的轮廓的编号,如果为负,绘制所有轮廓
  • color: 轮廓颜色
  • thickness: 轮廓线条粗细度,如果为负值(如thickness==cv_filled),绘制在轮廓内部
  • lineType: 线条类型
    • 8: 8连通线型
    • 4: 4连通线型
    • LINE_AA (OpenCV2: CV_AA): 抗锯齿线型
  • hierarchy: 可选层次结构
  • maxLevel: 绘制轮廓的最大等级
  • offset: 可选轮廓偏移参数

事例程序1

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector> // main
int main( int argc, char** argv )
{
// loading image
cv::Mat srcImage = cv::imread("1.jpg", );
imshow("original image", srcImage); // initialize result image
cv::Mat dstImage = cv::Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3); // thresholding image
srcImage = srcImage > ;
imshow("thresholding image", srcImage); // finding contours
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
// for opencv 2
// cv::findContours(srcImage, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
// for opencv 3
cv::findContours(srcImage, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE); // iterate through all levels, and draw contours in random color
int index = ;
for (; index>=; index = hierarchy[index][]) {
cv::Scalar color(rand()&, rand()&, rand()&);
// for opencv 2
// cv::drawContours(dstImage, contours, index, color, CV_FILLED, 8, hierarchy);
// for opencv 3
cv::drawContours(dstImage, contours, index, color, cv::FILLED, , hierarchy); imshow("contours", dstImage);
cv::waitKey();
}
cv::imwrite("result.jpg", dstImage);
return ;
}

1.jpg

result.jpg

事例程序2

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector> #define WINDOW_NAME1 "original image"
#define WINDOW_NAME2 "contours" // global variables
cv::Mat g_srcImage;
cv::Mat g_grayImage;
cv::Mat g_cannyMat_output;
int g_nThresh = ;
int g_nThresh_max = ;
cv::RNG g_rng();
std::vector<std::vector<cv::Point> > g_vContours;
std::vector<cv::Vec4i> g_vHierarchy; // functions
void on_ThreshChange(int, void*); // main
int main( int argc, char** argv )
{
// change the text color of console
system("color 1F"); // loading image
g_srcImage = cv::imread("1.jpg", );
if (!g_srcImage.data){
std::cerr << "ERROR while loading image." << std::endl;
return false;
} // convert to gray-scale and blur
cv::cvtColor(g_srcImage, g_grayImage, cv::COLOR_BGR2GRAY);
cv::blur(g_grayImage, g_grayImage, cv::Size(,)); // create window
cv::namedWindow(WINDOW_NAME1, cv::WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage); // create tracker bar
cv::createTrackbar("Canny Threshold", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange);
on_ThreshChange(, ); cv::waitKey();
return ;
} void on_ThreshChange(int, void*)
{
cv::Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh*, ); cv::findContours(g_cannyMat_output, g_vContours, g_vHierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); cv::Mat drawing = cv::Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
for (int i = ; i<g_vContours.size(); i++) {
cv::Scalar color(g_rng.uniform(, ), g_rng.uniform(, ), g_rng.uniform(, ));
cv::drawContours(drawing, g_vContours, i, color, , , g_vHierarchy);
}
imshow(WINDOW_NAME2, drawing);
}

结果图:

 

 

查找并绘制轮廓[OpenCV 笔记XX]的更多相关文章

  1. 图像显示 imshow()[OpenCV 笔记5]

    void imshow(const string& winname InputArray mat); winname 窗口表识名称 mat 需要显示的图像.InputArray类型,声明如下 ...

  2. 实例:图形绘制[OpenCV 笔记15]

    DrawShapes.cxx # include "DrawShapes_utils.h" #define WINDOW_NAME1 "Painting 1" ...

  3. OpenCV基本架构[OpenCV 笔记0]

    最近正在系统学习OpenCV,将不定期发布笔记,主要按照毛星云的<OpenCV3编程入门>的顺序学习,会参考官方教程和文档.学习工具是Xcode+CMake,会对书中一部分内容更正,并加入 ...

  4. 访问图像中的像素[OpenCV 笔记16]

    再更一发好久没更过的OpenCV,不过其实写到这个部分对计算机视觉算法有所了解的应该可以做到用什么查什么了,所以后面可能会更的慢一点吧,既然开了新坑,还是机器学习更有研究价值吧... 图像在内存中的存 ...

  5. Core模块其他常用知识点[OpenCV 笔记14]

    Matx 轻量级的Mat,必须在使用前规定好大小,比如一个2x3的float型的Matx,可以声明为Matx23f Vec Vec是Matx的一个派生类,是一个一维的Matx,跟vector很相似.在 ...

  6. 颜色空间转换 cvtColor()[OpenCV 笔记13]

    void cvtColor(InputArray src, OutputArray dst, ) src: 输入图像 dst: 输出图像 code: 颜色空间转换标识符 OpenCV2的CV_前缀宏命 ...

  7. 图像储存容器Mat[OpenCV 笔记11]

    IplImage 与 Mat IplImage是OpenCV1中的图像存储结构体,基于C接口创建.在退出之前必须release,否则就会造成内存泄露.在一些只能使用C语言的嵌入式系统中,不得不使用. ...

  8. 鼠标操作[OpenCV 笔记10]

    ) winname 窗口名字 onMouse 指定窗口每次鼠标事件发生的时候,被调用的函数指针.函数的原型应为void Foo(int event, int x, int y, int flags, ...

  9. 滑动条 Trackbar[OpenCV 笔记9]

    OpenCV中没有实现按钮的功能,我们可以利用滑动条来实现按钮功能. , ); trackbarname 轨迹条的名字. winname 窗口的名字,轨迹条会依附在这个窗口上. value 一个指向整 ...

随机推荐

  1. API功能测试如何实施(转载自测试之道 微信公众号)

    什么是API 关于定义什么的,直接维基可得: API(Application Programming Interface,简称:API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定.由于近 ...

  2. XMPP——Smack[5]文件传输及离线消息的获取

    三天时间,赶在最后一下午实现了文件的传输,本来需要实现离线文件的发送的,一直没想好怎么弄,找openfire的离线文件插件没找到,后来想出一种方法,起服务器时起了一个系统用户,一直在线,当用户发送离线 ...

  3. ThinkPHP3.1快速入门(13)自动完成

    自动完成是ThinkPHP提供用来完成数据自动处理和过滤的方法,使用create方法创建数据对象的时候会自动完成数据处理.因此,在ThinkPHP使用create方法来创建数据对象是更加安全的方式,而 ...

  4. SQLSERVER中返回修改后的数据

    在公司看到同事写了个SQL2005的新特性的文章,觉得很实用,在这里和大家分享下. 这种技术主要是用到了inserted和deleted虚拟表,这两张表相信大家都很熟悉.以前我们主要是在触发器中使用. ...

  5. 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 &amp; 3236 [Ahoi2013] 作业 题解

    [原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 978  Solved: 476 Descri ...

  6. mysql-connector-python

    wget http://cdn.mysql.com//Downloads/Connector-Python/mysql-connector-python-2.1.3.tar.gz tar mysql- ...

  7. 双tomcat的部署

    由于开发环境使用的tomcat需频繁开启关闭,所以决定另外搭建一个tomcat部署后台供前台调用接口,顺便记录一下备忘 我的部署环境为windows7 tomcat7 将下载的tomcat放到其他位置 ...

  8. eclipse @override错误

    @Override是JDK5 就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override而JDK6 修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现都可以加上@Over ...

  9. Zend Studio 10正式版注册破解

    1.文件和汉化文件 ZendStudio官方下载地址:http://www.geekso.com/component/zendstudio-downloads/ 百度云地址: 10.0.0.msi文件 ...

  10. svn :Can't connect to host *.*.*.*': 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

    Can't connect to host *.*.*.*': 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败. -------------------------------- ...