OpenCV2.4.13中同一函数不同形参的理解,vector,list区别,findContours理解
2017-12-13 20:04
363 查看
OpenCV手册中的函数通常有不止一个定义,其中的形参可以有各种不同的形式,这里以 split 和 merge 两个函数举例进行解释。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/05/18ba15e60c0661df802d55184849e3c3)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/05/2fada502d9b21f6df5f626df0a32abe6)
每个函数都有两个版本,一个版本利用数组作为形参,一个版本利用 vector 作为形参。
以split 为例,解释一下两个版本中形参的含义
void split(const Mat& src, Mat* mvbegin)
第一个形参:const 表示 src 不能修改;Mat& 表示使用 引用传递
第二个形参:分割之后的图像用一个Mat数组来存放,因此,对应的形参是 Mat*
void split(InputArray m, OutputArrayOfArrays mv)
第一个形参:InputArray 表示输入是“数组”
第二个形参:OutputArrayOfArrays 表示输出是 “数组的数组”
下面给出测试代码:
问题:为什么 可以用 vector 代替 数组呢?
这里的 vector 和 list 看起来长得很像,它们之间有什么关系呢?
问题:那么如何使用 vector 与 list 呢?如何遍历它们呢?
下面借用这里的代码展示如何使用 vector 与 list
问题:说了这么多有什么用呢?为甚么会写这篇博客呢?
因为楼主在使用 OpenCV 找图像的边界的时候遇到了一句这样的代码
我的天啊,这是一个什么鬼?
经过逐步搜索,才找到了答案,也就是上面描述的这些东东。
那如何找边界呢?
贴出代码如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/05/944aaf1c4850f135ed0e19a0bd8d07d8)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/05/24725034eec0d5805fdf8576f5da2f10)
整体代码如下:
每个函数都有两个版本,一个版本利用数组作为形参,一个版本利用 vector 作为形参。
以split 为例,解释一下两个版本中形参的含义
void split(const Mat& src, Mat* mvbegin)
第一个形参:const 表示 src 不能修改;Mat& 表示使用 引用传递
第二个形参:分割之后的图像用一个Mat数组来存放,因此,对应的形参是 Mat*
void split(InputArray m, OutputArrayOfArrays mv)
第一个形参:InputArray 表示输入是“数组”
第二个形参:OutputArrayOfArrays 表示输出是 “数组的数组”
下面给出测试代码:
int m = 300; Mat img = 255*Mat::eye(m,m,CV_8UC3); // 利用数组作为形参 Mat mv[3]; split(img,mv); for (int i = 0; i < 3; i++) imshow("array channel " + to_string(i),mv[i]); Mat mergeimg; merge(mv,3,mergeimg); imshow("merge image",mergeimg); // 利用 vector 作为形参 vector<Mat> mv2; split(img,mv2); for (int i = 0; i < 3; i++) imshow("vector channel " + to_string(i),mv2.at(i)); merge(mv2,mergeimg);
问题:为什么 可以用 vector 代替 数组呢?
这里的 vector 和 list 看起来长得很像,它们之间有什么关系呢?
名称 | vector | list |
---|---|---|
实现方式 | 与数组类似 | 利用链表实现 |
存储空间 | 连续 | 不连续 |
随机存储时间复杂度 | O(1) | O(n) |
插入与删除时间复杂度 | O(n) | O(1) |
下面借用这里的代码展示如何使用 vector 与 list
vector<int> v; // 这里 vector 中存放的元素都为 int 型 list<int> l; for(int i=0;i<8;i++) ////往v和l中分别添加元素 { v.push_back(i); l.push_back(i*i); } // 遍历 vector 有两种方法,一种是与数组一样 cout <<"v is: "<<endl; for (int i = 0; i<v.size(); i++ ) cout << v[i] << " "; cout <<endl; // 第二种是使用迭代器 // 定义迭代器,分别遍历 vector vector<int>::iterator itv; cout <<"v is: "<<endl; for (itv = v.begin(); itv != v.end(); itv++ ) cout << *itv << " "; cout <<endl; // 遍历 list 只能使用迭代器 进行遍历 //cout << l[0]; 编译错误,list 没有重载 [] list<int>::iterator itl; cout <<"l is: "<<endl; for (itl = l.begin(); itl != l.end(); itl++ ) cout << *itl << " "; cout <<endl;
问题:说了这么多有什么用呢?为甚么会写这篇博客呢?
因为楼主在使用 OpenCV 找图像的边界的时候遇到了一句这样的代码
vector<vector<Point>> contours;
我的天啊,这是一个什么鬼?
经过逐步搜索,才找到了答案,也就是上面描述的这些东东。
那如何找边界呢?
贴出代码如下:
// 将第一层的左上部分变成非零 for (int i = 0; i < img.rows/2; i++) for (int j = 0; j < img.cols/2; j++) mv[0].at<uchar>(i,j) = 255; imshow("mv[0]",mv[0]); // 效果如下:
// 找图像的边界 // 有好多个边界(对应最外面的vector), //每一个边界是一系列点的集合(对应里面的vector<Point>) vector<vector<Point>> contours; findContours(mv[0],contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); Scalar color = Scalar(0,0,255); drawContours(img,contours,-1,color); imshow("img with contours",img); // 效果如下:
整体代码如下:
// csdn_code.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; int main() { int m = 300; Mat img = 255*Mat::eye(m,m,CV_8UC3); // 利用数组作为形参 Mat mv[3]; split(img,mv); for (int i = 0; i < 3; i++) imshow("array channel " + to_string(i),mv[i]); Mat mergeimg; merge(mv,3,mergeimg); imshow("merge image",mergeimg); // 利用 vector 作为形参 vector<Mat> mv2; split(img,mv2); for (int i = 0; i < 3; i++) imshow("vector channel " + to_string(i),mv2.at(i)); merge(mv2,mergeimg); vector<int> v; // 这里 vector 中存放的元素都为 int 型 list<int> l; for(int i=0;i<8;i++) ////往v和l中分别添加元素 { v.push_back(i); l.push_back(i*i); } // 遍历 vector 有两种方法,一种是与数组一样 cout <<"v is: "<<endl; for (int i = 0; i<v.size(); i++ ) cout << v[i] << " "; cout <<endl; // 第二种是使用迭代器 // 定义迭代器,分别遍历 vector vector<int>::iterator itv; cout <<"v is: "<<endl; for (itv = v.begin(); itv != v.end(); itv++ ) cout << *itv << " "; cout <<endl; // 遍历 list 只能使用迭代器 进行遍历 //cout << l[0]; 编译错误,list 没有重载 [] list<int>::iterator itl; cout <<"l is: "<<endl; for (itl = l.begin(); itl != l.end(); itl++ ) cout << *itl << " "; cout <<endl; // 将第一层的左上部分变成非零 for (int i = 0; i < img.rows/2; i++) for (int j = 0; j < img.cols/2; j++) mv[0].at<uchar>(i,j) = 255; imshow("mv[0]",mv[0]); // 效果如下: // 找图像的边界 vector<vector<Point>> contours; findContours(mv[0],contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); Scalar color = Scalar(0,0,255); drawContours(img,contours,-1,color); imshow("img with contours",img); // 效果如下: waitKey(); system("pause"); return 0; }
相关文章推荐
- List、Map、Set的理解(LinkedList和ArrayList、Vector和ArrayList、HashMap和HashTable和HashSet区别与使用)
- OpenCV2.4.13中warpAffine函数理解,旋转,仿射变换,缩放,保持完整图片
- Clojure中Vector和List的区别及其相关函数
- List、Map、Set的理解(LinkedList和ArrayList、Vector和ArrayList、HashMap和HashTable和HashSet区别与使用)
- ArrayList、LinkedList以及Vector的基础函数与区别
- arrayList 和 LinkedList ,Vector 的区别
- vector与list区别
- Java中List,ArrayList、Vector,map,HashTable,HashMap区别用法
- Set,List,Map,Vector,ArrayList的区别
- ArrayList Vector LinkedList 区别与用法
- java的List接口的实现类 ArrayList,LinkedList,Vector 的区别
- ARRAYLIST VECTOR LINKEDLIST 区别与用法
- 区别:&nbsp;vector&nbsp;list&nbsp;deque&nbsp;set&nbsp;map(…
- java中ArrayList、LinkedList和Vector的区别
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
- List、ArrayList、Vector及map、HashTable、HashMap的区别与用法
- STL中: string、vector、list、deque、set、map 的区别
- ArrayList、LinkedList、Vector的区别
- vector,map,list,queue区别
- Java中LinkedList、Vector和ArrayList的区别