OpenCV(C++版)入门
了解Opencv
喜欢的可以点赞收藏转发关注
Opencv是一个开源的计算机视觉编程程序库,可在windows,Linux,Mac,Android,iOS上面运行。目前Opencv已经到了第3版,增加了许多功能,API也全部迁移到了C++,当然也有Python版本。并且第三版还增加一个独立的最新算法库(contrib库),其中包含一些最新的算法,可能需要收费,但这些算法仍然在开发中,经常会被修改,没有特殊需求一般不需要使用。
Opencv包含多个模块,core模块包含核心功能,imgproc模块包含图像处理,highgui模块包含读写图像和视频的一些函数,在使用这些模块之前,需要包含头文件。
#include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp>
图像对象
在Opencv中,图像对象的数据是由Mat来表示的。对计算机来说,图像就是一个矩阵,因此Mat最主要的部分就是一个矩阵数据。除此之外,Mat还包括一些图像的属性,比如图像的长度、宽度、通道数等,我们可以用rows,cols,channels()来获取这些属性。
Mat image1 ( 240 , 320 , CV_8U , 100 ); cout << image1 . cols << image1 . rows << image1 . channels ();
除了图像的属性外,图像的像素也有它自己的格式。像素就是矩阵中的一个数据,这个数据的大小就表示了颜色的深浅。由于图像的通道包括单通道的和多通道的,所以像素也分为两种,单通道的就是一个数据就可以,多通道的需要多个数字组成一个像素。最常见的像素格式就是CV8U,这表示这是单通道的像素格式,或者说为一个灰度图像,它的像素值为8个字节,用C++中unsigned char数据类型表示。另一个彩色图像的像素可以用CV8UC3来表示,8U含义与单通道的一样,C3表示三个通道(channels),表示彩色像素类型,由三个数据RGB表示。若是灰度图像,则这三个RGB数据都相等。
opencv还能够进行图像的读取、展示、保存,读取图像使用imread()函数,保存图像使用imwrite(),展示图像使用imshow()。在读取时,还能够自行选择图像的读取格式,常用的有IMREADGRAYSCALE和IMREADCOLOR,前一个表示灰度图像,后一个表示RGB图像。
Mat image = imread ( "demo.jpg" , IMREAD_COLOR ); imshow ( "Image" , image ); // show the image imwrite ( "test.jpg" , image ); waitKey ( 0 ); // wait for a key pressed
waitKey(0)则表示在展示图像的时候,在等待规定时间内接受一个按键再进行下一步的操作,如果等待时间设为0,则表示一直等待下去。
Mat是Opencv经过高度优化的数据结构,它自带了内存管理,可以通过检测引用数来释放不需要的内存。同时它的赋值操作也分为浅赋值和深复制,浅赋值能够不必复制大量的数据,从而提高程序的性能,最好只在需要深复制时在进行深复制。
在赋值或者初始化时,使用的是浅赋值,这样变量的指针指向的是同一个数据。
cv :: Mat image2 ( image1 ); image3 = image2 ;
如上所示,image1,image2,image3指向的都是内存中同一块数据,所以只要修改其中一个任意一个变量,其他的都会改变。
而在进行深赋值时,需要使用函数copyTo(),或者clone(),这样复制出来的就是两个不同的内存数据块,这样就可以随意修改数据也不会影响其他的了。
其他对象
Point表示点类型,常用来表示坐标。Size表示尺寸,常用来表示图像的大小。Scalar表示色彩,用来表示图像的颜色。还有InputArray表示一个输入数组的代理,由于使用Mat可能会造成参数不兼容,所以Opencv中的函数使用的都是InputArray,同时还有OutputArray对象,表示输出数组的代理。
有时候还会遇到需要小矩阵的情况,这时候可以使用模板类Matx和它的子类。例如定义一个3*3的双精度型的浮点数矩阵可以使用Matx33d,定义一个3元素的向量可以使用Matx31d。这些矩阵还支持矩阵之间的操作,比如相乘相加等。
cv :: Matx33d matrix ( 3.0 , 2.0 , 1.0 , 2.0 , 1.0 , 3.0 , 1.0 , 2.0 , 3.0 ); cv :: Matx31d vector ( 5.0 , 1.0 , 3.0 ); cv :: Matx31d result = matrix * vector ;
获取ROI
ROI就是Region of Interest,表示感兴趣的区域。有时候我们只想获取一部分区域,那就需要用到ROI了。ROI实际上就是一个Mat对象,同时他和他的父图像指向的是同一个数据缓冲区,所以改变ROI也就能改变它的父图像了。
imageROI = image ( cv :: Rect ( image . cols - logo . cols , image . rows - logo . rows , logo . cols , logo . rows ));
如上代码所演示,ROI可以直接使用Rect来定义,我们可以使用图像的大小和logo的大小来确定ROI的大小,接下来改变imageROI就会改变原始图像image。
另一种定义ROI的方式是使用Range结构,即从开始索引到结束索引的一片连续区域,但是行和列需要分别来定义。
imageROI = image ( cv :: Range ( image . rows - logo . rows , image . rows ), cv :: Range ( image . cols - logo . cols , image . cols ));
还能直接定义行和列组成的ROI,这样只能选择由特定区域的行或者列,但不是特别灵活。
imageROI = image . rowRange ( start , end ); imageROI = image . colRange ( start , end );
上面主要介绍了opencv的一些基础知识,不过想熟练使用,还得多加练习才是。
如果你想了解或者学习C++,欢迎大家加入C++组织,评论+私信扣6,有关必回。记得点赞哦!