OpenCV从入门到放弃(三):Core组件细讲
2016-09-07 16:33
645 查看
Core组件由名字就知道是最核心功能的模块:在Core组件中,包含了最基本的数据结构,动态数据结构,画图的一些函数和一些系统函数.下面依次来讲一下这些基本的功能.Core组件是很重要的相当于修楼房的砖块,要把一些基本的概念弄懂.
按照pyton的方式输出矩阵,同时还有一点点红色出现在框里面.这是矩阵的输出方式.
结果及其分析:
1.首先就一整个来说,
因为namewindow()了六个窗口.但是其中有一个”image”窗口变色了.
是因为上面这段代码初始化了一个灰度图(CV_8U)然后在”image”命名的这个窗口显示导致的.
2.按一下回车.
其他都没有变,那个image窗口变小了,而且颜色也变了.
是因为下面这段代码导致的
也就是说.这个时候的image1这个mat对象被重新改变了size和值.
3.按一下回车
其他的没有变,只有“image”这个窗口变了。是下面这段代码改变的。
这段代码新建了一个image2的mat对象,并且是三通道彩色的(CV_8UC3)。初始的值设为红色。然后Image这个窗口用来显示image2这个对象了。(这个例子说明。一个窗口用了之后还能够给其他的对象再用。)
4.按一下回车
这次改变就蛮大了.
上面这段代码先是建立了一个image3的对象,并且都载入了一张图像
原图是这个样子的
然后就浅复制给image4,然后就深复制给image5.然后image3翻转。
我们看到,image4和image3都翻转了。但是image5没有翻转。因为image5是深度复制变得独立。不受image3翻转的影响。
5.按一下回车
Image窗口变成灰色,
得到的结论是:
1.可以随时用create方法分配或者重新分配图像的数据块,要是图像已经分配,首先其原来的内容会被释放。(要是新的大小和类型都与原来的相同,就不会重新分配内存)
2.一旦没有了指向cv::Mat对象的引用,那么这个对象就会被自动释放。
3.在两个图像之间赋值的时候(包括赋值=或者复制构造函数等等),图像数据并不会被复制,此时两个图像都指向同一个内存块。所以,这样的出来的图像有可能会影响到其他的图像
4.要想深度复制图形的话,可以用copyTo()方法或者clone()方法。
5.如果你需要把一个图像复制到另外一个图像中,但是两者的数据类型是不一样的,那么就要是用convertTo方法
http://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2
效果:
效果:
看了效果之后,应该对于这个椭圆的各个角度应该有了认识.
结果:
结果:
一:基本数据结构
1.Mat类(最基本的数据结构)
1.概念
1.Mat不仅仅是一个图像容器类,同时也是一个通用的矩阵类. 2.不必再手动为其开辟空间,也不必在不需要的时候立即将他的空间释放 3.Mat是一个类,由两个数据部分组成: 1.矩阵头:矩阵尺寸,存储方法,存储地址等等所有相关信息(矩阵头的尺寸是常数值) 2.指向存储所有像素值数据块的指针. 4.赋值运算符和复制构造函数只会复制信息头和指向数据块指针的值.但是不会完整的复制一个矩阵(为了性能和避免内存溢出考虑).所以有多个对象引用同一个值矩阵,改变其中一个对象有改变其他的对象的可能. 5.使用clone()或者copyTo()来深层复制一幅图像的矩阵. 6.前面已经知道一个矩阵可以被多个Mat对象引用,那么最后一个使用这个矩阵的对象,负责清理矩阵。
2.常用函数
1.构造函数(主要介绍下面这两种)
Mat (int rows, int cols, int type, const Scalar &s) Rows:行数 Cols:列数 Type:类型 CV_[位数][带符号与否][类型前缀][通道数] 例:CV_8UC3表示使用8位的unsighed char类型.每个像素由三个元素组成的三通道. 类型汇总: CV_8U (8 bit 无符号整形0~255) CV_8UC1 (1通道) CV_8UC2 (2通道) CV_8UC3 (3通道) CV_8UC4(4通道) CV_8S (8 bit有符号整形-128~127) CV_8SC1 (1通道) CV_8SC2 (2通道) CV_8SC3 (3通道) CV_8SC4 (4通道) CV_16U (16 bit 无符号整形0~65535) CV_16UC1 (1通道) CV_16UC2 (2通道) CV_16UC3 (3通道) CV_16UC4 (4通道) CV_16S (16 bit 有符号整形-32768~32767) CV_16SC1(1通道) CV_16SC2(2通道) CV_16SC3(3通道) CV_16SC4(4通道) CV_32S (32 bit 有符号整形-2147483648~2147483647) CV_32SC1 CV_32SC2 CV_32SC3 CV_32SC4 CV_32F (32 bit 浮点) CV_32FC1 CV_32FC2 CV_32FC3 CV_32FC4 CV_64F (64 bit 浮点) CV_64FC1 CV_64FC2 CV_64FC3 CV_64FC4 Scalar:颜色类..具体看下面的Scalar类. Mat (int ndims, const int *sizes, int type, const Scalar &s) Ndims:维数. *size:一个数组,表示相应维数下面的具体数量 Type:和上面一样 Scalar:和上面一样.
2.empty()函数(判断是否Mat是否有元素,或者是否分配了图像数据)
使用方法:Mat对象.empty() 返回一个bool对象.
3.channels()函数
返回一个Mat对象的通道数.
4.create()函数
这个方法不能够为矩阵设置初值,只是在改变尺寸的时候重新为矩阵开辟内存而已.
5.type()函数 返回的是一个int值.返回mat的类型.
3.例子
1.Mat的初始化和输出
我们在这里使用的初始化是标准的Mat()构造函数的方法,输出方法是Python风格的输出(以后也会固定这样的创建和输出风格.)按照pyton的方式输出矩阵,同时还有一点点红色出现在框里面.这是矩阵的输出方式.
2.Mat的内存管理方式(这个例子非常重要)
代码:结果及其分析:
1.首先就一整个来说,
因为namewindow()了六个窗口.但是其中有一个”image”窗口变色了.
是因为上面这段代码初始化了一个灰度图(CV_8U)然后在”image”命名的这个窗口显示导致的.
2.按一下回车.
其他都没有变,那个image窗口变小了,而且颜色也变了.
是因为下面这段代码导致的
也就是说.这个时候的image1这个mat对象被重新改变了size和值.
3.按一下回车
其他的没有变,只有“image”这个窗口变了。是下面这段代码改变的。
这段代码新建了一个image2的mat对象,并且是三通道彩色的(CV_8UC3)。初始的值设为红色。然后Image这个窗口用来显示image2这个对象了。(这个例子说明。一个窗口用了之后还能够给其他的对象再用。)
4.按一下回车
这次改变就蛮大了.
上面这段代码先是建立了一个image3的对象,并且都载入了一张图像
原图是这个样子的
然后就浅复制给image4,然后就深复制给image5.然后image3翻转。
我们看到,image4和image3都翻转了。但是image5没有翻转。因为image5是深度复制变得独立。不受image3翻转的影响。
5.按一下回车
Image窗口变成灰色,
得到的结论是:
1.可以随时用create方法分配或者重新分配图像的数据块,要是图像已经分配,首先其原来的内容会被释放。(要是新的大小和类型都与原来的相同,就不会重新分配内存)
2.一旦没有了指向cv::Mat对象的引用,那么这个对象就会被自动释放。
3.在两个图像之间赋值的时候(包括赋值=或者复制构造函数等等),图像数据并不会被复制,此时两个图像都指向同一个内存块。所以,这样的出来的图像有可能会影响到其他的图像
4.要想深度复制图形的话,可以用copyTo()方法或者clone()方法。
5.如果你需要把一个图像复制到另外一个图像中,但是两者的数据类型是不一样的,那么就要是用convertTo方法
2.Scalar类(颜色表示)
1.概念
1.Scalar类源头为scalar_类,typedef Scalar_< double > cv::Scalar后成为scalar类 2.Scalar表示具有4个元素的数组,一般在OpenCV中被用来传递像素值.
2.函数
就举一个简单的构造函数cv::Scalar_< _Tp >::Scalar_ ( _Tp v0,_Tp v1,_Tp v2 = 0,_Tp v3 = 0 )
3.用法
一般的用法就是Scalar(a,b,c)表示一个颜色对象.注意:顺序分别是蓝,绿,红.在上面Mat的构造函数中就有Scalar的使用.回过头来看一下是不是豁然开朗?3.Point类(点的表示)
1.概念
Point类表示二维坐标系下面的点.
2.函数
举两个常用的构造函数Point_ (_Tp _x, _Tp _y) //代入坐标 Point_ (const Point_ &pt) //代入点
3.用法
Point p=Point(1,2) //p就表示一个坐标(1,2)的点 等价于 Point p; p.x=1; p.y=2;
4.Size类(尺寸的表示)
1.概念
就是表示尺寸的一个类,来源于Size_()
2.函数
Size_ (_Tp _width, _Tp _height) 其实就是宽和高
3.用法
Size(3,4) //宽和高分别是3,4
5.Rect类(矩形的表示)
1.概念
表示一个矩形的类,来源是Rect_< _Tp >
2.函数
常用的构造函数: Rect_ (_Tp _x, _Tp _y, _Tp _width, _Tp _height) //传坐标和宽高 Rect_ (const Rect_ &r) //传rect对象 Rect_ (const Point_< _Tp > &org, const Size_< _Tp > &sz) //传入点(得到坐标)尺寸(得到宽高) 普通函数 _Tp area () const //返回矩形面积 Point_< _Tp > br () const //返回右下角点坐标 bool contains (const Point_< _Tp > &pt) const //判断某点是否在矩形内 Size_< _Tp > size () const //返回当前矩形的Size Point_< _Tp > tl () const //返回左上角点坐标
3.用法
就这么用…二.绘图函数
首先要讲一下,接下来的大部分函数都在cv::LineIterator这个类下面.画直线等等函数在imgproc这个模块中.之所以放在Core这个组件讲,是因为前面刚刚讲了Opencv中的一些基本的数据结构.绘图函数本身也是十分重要的函数且用到之前讲过的概念.因此,提前放在这里讲.下面是绘图函数的官方文档.http://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2
1.直线(line)
1.函数及其使用方式
void cv::line ( InputOutputArray img, Point pt1, Point pt2, const Scalar & color, int thickness = 1, int lineType = LINE_8, int shift = 0 ) Img:待操作的图片 pt1:起点 Pt2:终点 Color:颜色 Thickness:厚度(粗细) LineType:直线类型 Shift:
2.实例
代码:#include <iostream> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> //画直线等等函数在imgproc中 #include <opencv2/imgproc.hpp> int main() { //创建一个窗口并且以Tset为标示 cv::namedWindow("Test"); //创建空白的图像 cv::Mat Image = cv::Mat::zeros(600, 600, CV_8UC3); //起点和终点 cv::Point p1(100, 200); cv::Point p2=cv::Point(100, 400); cv::Point p3(150, 200); cv::Point p4 = cv::Point(150, 400); cv::Point p5(200, 200); cv::Point p6 = cv::Point(200, 400); cv::Point p7(250, 200); cv::Point p8 = cv::Point(250, 400); //画直线1 cv::line(Image, p1, p2, cv::Scalar(0, 0, 255), 1, 8, 0); //画直线2(改变了线条粗细) cv::line(Image, p3, p4, cv::Scalar(0, 0, 255), 10, 8, 0); //画直线3(改变了线条类型) cv::line(Image, p5, p6, cv::Scalar(0, 0, 255), 1, 4, 0); //画直线4(改变了shift) cv::line(Image, p7, p8, cv::Scalar(0, 0, 255), 1, 8, 0); cv::imshow("Test", Image); cv::waitKey(0); return 0; }
效果:
2.椭圆(ellipse)
1.函数使用方式
void cv::ellipse ( InputOutputArray img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar & color, int thickness = 1, int lineType = LINE_8, int shift = 0 ) Img:待操作的图片 Center:椭圆中心点坐标 Axes:是一个size的类型,其实就是长短轴的大小(最终肯定是位于一个矩形框里面) Angle:表示椭圆的旋转角度 startAngle:开始扩展弧度 endAngle:结束的扩展弧度 Color:颜色 Thickness:厚度(粗细) LineType:线类型 Shift:
2.实例
代码:#include <iostream> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> //画直线等等函数在imgproc中 #include <opencv2/imgproc.hpp> int main() { //创建一个窗口并且以Tset为标示 cv::namedWindow("Test"); //创建空白的图像 cv::Mat Image = cv::Mat::zeros(600, 600, CV_8UC3); //中心点和长短轴 cv::Point c1(100, 200); cv::Size ax1(50, 100); cv::Point c2(250, 200); cv::Size ax2(50, 100); cv::Point c3(400, 200); cv::Size ax3(50, 100); //画椭圆1,中心(100,200),短轴50,长轴100,旋转角度为0°,扩展弧长为(0,360) //颜色,粗细等等可以类比前面讲过的直线 cv::ellipse(Image, c1, ax1, 0, 0, 360, cv::Scalar(0, 0, 255), 1, 8, 0); //画椭圆2,中心(250,200),短轴50,长轴100,旋转角度为30°,扩展弧长为(0,360) //颜色,粗细等等可以类比前面讲过的直线 cv::ellipse(Image, c2, ax2, 30, 0, 360, cv::Scalar(0, 0, 255), 1, 8, 0); //画椭圆3,中心(400,200),短轴50,长轴100,旋转角度为30°,扩展弧长为(90,360) //颜色,粗细等等可以类比前面讲过的直线 cv::ellipse(Image, c3, ax3, 30, 90, 360, cv::Scalar(0, 0, 255), 1, 8, 0); cv::imshow("Test", Image); cv::waitKey(0); return 0; }
效果:
看了效果之后,应该对于这个椭圆的各个角度应该有了认识.
3.矩形(rectangle)
1.函数使用方式
方式一: void cv::rectangle ( InputOutputArray img, Point pt1, Point pt2, const Scalar & color, int thickness = 1, int lineType = LINE_8, int shift = 0 ) Img:待操作的图片 pt1:顶点坐标 Pt2:对角线那个顶点的坐标 Color:颜色 Thickness:厚度(粗细) LineType:线类型 Shift: 方式二: void cv::rectangle ( Mat & img, Rect rec, const Scalar & color, int thickness = 1, int lineType = LINE_8, int shift = 0 ) Img:待操作的图片 Rec:矩阵对象 Color:颜色 Thickness:厚度(粗细) LineType:线类型 Shift:
2.实例
代码:#include <iostream> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> //画直线等等函数在imgproc中 #include <opencv2/imgproc.hpp> int main() { //创建一个窗口并且以Tset为标示 cv::namedWindow("Test"); //创建空白的图像 cv::Mat Image = cv::Mat::zeros(600, 600, CV_8UC3); //两个顶点的方式创建矩形框 cv::Point p1(100, 200); cv::Point p2(300, 400); cv::rectangle(Image, p1, p2, cv::Scalar(0, 0, 225), 1, 8, 0); //rect的方式创建矩形框 cv::rectangle(Image, cv::Rect(300, 300, 100, 200), cv::Scalar(255, 0, 0), 1, 8, 0); cv::imshow("Test", Image); cv::waitKey(0); return 0; }
结果:
4.圆(circle)
1.函数使用方式
void cv::circle ( InputOutputArray img, Point center, Int radius, const Scalar & color, int thickness = 1, int lineType = LINE_8, int shift = 0 ) Img:待操作的图片 center:中心点坐标 Radius:半径 Color:颜色 Thickness:厚度(粗细) LineType:线类型 Shift:
2.实例
代码:#include <iostream> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> //画直线等等函数在imgproc中 #include <opencv2/imgproc.hpp> int main() { //创建一个窗口并且以Tset为标示 cv::namedWindow("Test"); //创建空白的图像 cv::Mat Image = cv::Mat::zeros(600, 600, CV_8UC3); //创建圆 cv::Point c1(100, 200); cv::circle(Image, c1, 50, cv::Scalar(0, 0, 255), 1, 8, 0); cv::imshow("Test", Image); cv::waitKey(0); return 0; }
结果:
相关文章推荐
- OpenCV从入门到放弃(四):HighGui组件细讲
- [Learning OpenCV入门3] OpenCV数据结构及core组件
- OpenCV从入门到放弃系列之——core模块.核心功能(一)
- OpenCV2入门——core组件之基础画图与算法实现
- OpenCV2入门——core组件之Mat详解
- [Learning OpenCV入门 3]OpenCV的数据结构及core组件【未完待续】
- 【转】【OpenCV入门教程之二】 :OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
- 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
- OpenCV从入门到放弃(七):直方图那些事儿
- OpenCV从入门到放弃(五):像素!
- 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
- OpenCV基础入门 基于官方文档解读(3)--core模块学习
- OpenCV_(5):core组件常用函数
- OpenCV从入门到放弃(二):架构和上手
- OpenCV3——core组件进阶
- 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
- 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
- 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
- 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8组件结构全解析
- 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8组件结构全解析