1. 例程
1 // 轮廓寻找 2 3 #include "stdafx.h" 4 #include <opencv2corecore.hpp> 5 #include <opencv2imgprocimgproc.hpp> 6 #include <opencv2highguihighgui.hpp> 7 #include <iostream> 8 #include <map> 9 #include <string> 10 #include<stdio.h> 11 12 using namespace std; 13 using namespace cv; 14 15 16 void main() 17 { 18 19 Mat image = imread("03.jpg"); 20 21 Mat gray; 22 cvtColor( image, gray, CV_RGB2GRAY); 23 24 Mat binary; 25 threshold( gray, binary, 150, 255, CV_THRESH_BINARY_INV); 26 27 vector<vector<Point>> contours; 28 Mat binary_copy; 29 binary.copyTo(binary_copy); 30 findContours( binary_copy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); // CV_RETR_EXTERNAL 获取外轮廓 CV_CHAIN_APPROX_NONE 获取每个轮廓的像素 31 32 // 遍历每一个轮廓,把多余的轮廓去掉 33 vector<vector<Point>>::iterator it = contours.begin(); 34 while (it != contours.end()) 35 { 36 if (it->size() < 500) 37 { 38 it = contours.erase(it); 39 } 40 else 41 it++; 42 } 43 44 // 重新绘制轮廓 45 Mat dst(image.size(), CV_8U, Scalar(0)); 46 drawContours( dst, contours, -1, Scalar(255), CV_FILLED); 47 48 // 显示结果(原图和结果图显示在一起) 49 const int width = image.cols; 50 const int height = image.rows; 51 Mat show_image(Size(width * 3,height), CV_8UC3); 52 // 将image拷贝到指定位置上 53 image.copyTo(show_image(Rect( 0, 0, width, height))); 54 // 将binary,dst 转换为三通道,使得 dst 和 show_image 通道数一致 55 cvtColor(binary, binary, CV_GRAY2BGR); 56 cvtColor(dst, dst, CV_GRAY2BGR); 57 58 // binary 和 dst拷贝到指定位置上 59 binary.copyTo(show_image(Rect(width, 0, width,height))); 60 dst.copyTo(show_image(Rect(width * 2, 0, width,height))); 61 62 // 显示 63 imshow("show", show_image); 64 drawContours( image, contours, -1, Scalar(0,255,0), CV_FILLED); 65 imshow("效果", image); 66 67 waitKey(0); 68 }
2.函数解释
void findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy , int mode, int method, Point offset=Point());
image 二值单通道图像
contours 检测的轮廓数组,每一个轮廓用一个 Point 类型的 vector 表示
hierarchy 轮廓个数相同,每一个轮廓 contours[i] 对应 4 个hierarchy[ i ][ 0 ] ~ hierarchy[ i ][ 3 ],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数
mode 表示轮廓的检索模式
CV_RETR_EXTERNAL 表示只检测外轮廓
CV_RETR_LIST 检测的轮廓不建立等级关系
CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为边界信息,如果内孔内还有一个连通物体,这个物体的边界也在顶层
CV_RETR_TREE 建立一个等级树结构的轮廓
method 轮廓的近似方法
CV_CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过 1,即max(abs( x1 - x2)), abs(y2 - y1) == 1
CV_CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如: 一个矩形轮廓只需4个点来保存轮廓信息
CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS 使用 teh-chinl 近似算法
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 轮廓组,对应 findContours 里的 contours
contourldx 指明第几个轮廓,如果是负数,则画出所有的轮廓
color 轮廓颜色
thickness 轮廓的线宽
lineType 如果是负数或者使用 CV_FILLED 表示填充轮廓内部
hierarchy 轮廓结构