- 机电产品创新应用开发技术
- 胡福文等
- 2667字
- 2020-04-14 18:36:29
2.3 OpenCV系统开发
2.3.1 OpenCV开发包安装
图像处理是使用计算机对图像分析获得有意义信息的一种技术手段。图像处理包括图像压缩,增强和复原,匹配、描述和识别等部分。OpenCV是一个基于开源的计算机平台视觉开发库,能够实现图像处理以及计算机视觉方面的很多通用算法。OpenCV官方网站为http://opencv.org,见图2-48。
图2-48
下载完后得到文件OpenCV 3.2.0,双击后会提示解压到某个地方,推荐放到D:\Program Files\,比如D:\Program Files(因为OpenCV项目文件打包的时候,根目录就是opencv,所以我们不需要额外的新建一个名为opencv的文件夹),然后单击“Extract”按钮,见图2-49。
图2-49
在解压的opencv文件夹中,build里面是使用OpenCV相关的文件,使用OpenCV的相关文件全部储存在build中,见图2-50。sources文件夹中存放着官方的实例集,可以删除。
图2-50
在“计算机”“属性”中单击“高级系统设置”,进入“高级”标签,单击“环境变量”按钮,在系统变量“PATH”后可以按下述情况添加,见图2-51。
图2-51
Opencv3.2.0官网只有x64,需要x86的读者需要自己编译。
对于64位系统,可以两个都添加上:“…… opencv\build\x64\vc\14\bin”。
本书将在vs2013中编译OpenCV,所以在使用前需要在vs2013中配置工程。打开visual studio,新建win32控制台项目,输入名字,选择文件路径,确定。在出现的对话框中勾选“空项目”。
在解决方案资源管理器的工程树中右击“源文件”,“添加”“新建项”,在工程中新建一个cpp源文件。
在菜单栏中单击“视图”“属性窗口”,在visual studio中会多出一个属性管理器工作区,见图2-52。
图2-52
在新出现的“属性管理器”工作区中,单击项目[Debug|x64][Microsoft.Cpp.x64.user]打开属性页面,见图2-53。
图2-53
在“通用属性”“VC++目录”“包含目录”中添加:
…\opencv\build\include
…\opencv\build\include\opencv
…\opencv\build\include\opencv2
配置库目录:在库目录中添加…\opencv\build\x64\vc14\lib路径,见图2-54。
图2-54
链接库的配置:在“属性管理器”工作区中,单击“项目”|“Debug|x64Microsoft.Cpp.x64.user”打开属性页面。在对话框中单击“通用属性”|“链接器”|“输入”|“附加的依赖项”将lib中的文件添加到“附加的依赖项”中,见图2-55。
图2-55
在OpenCV开发包安装过程中,可能会出现以下几种情况。
①找不到core.h:出现这个问题是因为include的时候,opencv根文件夹下面就有个include,但配置的时候,包含的应该是build中的include。
②无法解析的外部命令:是因为编译器与配置文件不符合,与系统无关,只与编译器的类型有关。使用32位编译器选择x86位配置文件,64位编译器选择x64位配置文件。
③关于形如-error LNK2005:xxx已经在msvcrtd.lib(MSVCR90D.dll)中定义,不包含静态库。
④应用程序无法正常启动0xc000007b:这属于Lib包含的问题。也许同时包含了x86和x64的,或者包含出错了。或者是对于windows 8 64位,.dll文件要放在和System32文件夹同级的SysWOW64文件夹中。
2.3.2 OpenCV开发实例:载入图像
在OpenCV中,所有的C++类和函数都是定义在cv命名空间内的,可以通过以下两种方法访问。第一种是在编写程序代码的开头位置,加上“usingnamespace cv;”。另外一种是在每次需要使用OpenCV类和函数时,都在类和函数前加上“cv::”。
Mat类:在OpenCV中,Mat类是用于保存图像以及其他矩阵数据的数据结构。Mat类的初始大小为0,也可以用户自己定义Mat类的空间大小。
例2-2 imread()函数:
Mat tupian=imread(“mao.jpg”)
表示将工程目录下的mao.jpg图片导入到Mat类tupain中。
Mat imread(const string& filename,intflags=1);
imread()函数中,第一个参数为需要载入的文件名,第二个参数为载入图像的颜色类型。
取值为0时,将图像转换从灰度图像再返回;取1时,将图像转换为彩色再返回;取2时,如果载入图像为16位或者32位,就返回对应深度的图像,否则,会将图形转换为8位图像再返回。
namedWindow()函数:
namedWindow()函数用于创建一个窗口。这个窗口可以作为图像和进度条的容器。但是如果相同名字的窗口已经创建,那么函数将不会做任何事情。当编写的程序量较大时,可以使用destroyWindow()或者destroyAllWindows()函数来关闭窗口。在退出时,所有的窗口都将被系统关闭。
void namedWindow(const string& winname,int flags=WINDOW_AUTOSIZE);
第一个参数为需要创建的窗口名称。
第二个参数是所创建的出口的类型标识,可以填如下的值。
WINDOW_NORMAL:用户可以自由改变窗口的大小。
WINDOW_AUTOSIZE:窗口能够根据图片大小自动调整大小,但是用户不能手动调整窗口大小,为函数的默认值。
WINDOW_OPENGL:创建的窗口支持OpenGL。
imshow()函数:在指定的窗口中显示一幅图像。在显示时,如果窗口的创建标识为默认格式,图片将以原始尺寸显示。否则图片将会被适度缩放,以适应窗口的大小。
void imshow(const string& winname,InputArray mat);
第一个参数中填写需要显示的窗口名称,第二个参数中填写需要显示的图像名称,见图2-56。
图2-56
imshow函数测试程序:
imwrite()函数是将图像保存到指定的文件的函数,图像格式由文件扩展名决定。
bool imwrite(const string& filename,InputArray img,const vector<int>¶ms=vector<int>());
第一个参数中填写需要写入的文件名,需要带上后缀,例如“1.jpg”。第二个参数中填写需要输出的图像名。第三个参数中为特定格式保存的参数编码,它有默认值,所以一般情况下可以省略,但是在以下地方可能用到:对于JPEG图片格式,参数表示图片质量,0~100,默认值为95;对于PNG图片格式,参数表示图片的压缩级别,0~9,值越大,压缩的尺寸越小,并且占用更多的压缩时间,默认值为3;对于PPM、PGM和PBM图片格式,参数表示二进制标志,取值为0/1,默认值为1。
ROI为设置感兴趣区域,即选定一块区域作为图像处理与分析的重点,这样可以减少处理时间,增加处理精度。
ROI创建函数[cv::Rect()和cv::Range()]
cv::Rect:创建一个矩形区域,需要指定矩形区域的左上角坐标和矩形长和宽。
Mat tp;
tp=image(Rect(300,200,200,100));
cv::Range:创建一个区域范围,从开始点到结束点的连续序列。
定义一个左上角坐标为(300,200),宽为200,高100的矩形窗口。
Mat tp;
tp=srcImage3(Range(100,150),Range(150,200));
这里截取的就是原图第100行至第149行,第150列到第199列的图像。Range的两个参数范围分别为左包含和右不包含。
2.3.3 OpenCV开发实例:图像叠加
混合是将2幅图像的像素值进行加权,形成新的图像,见图2-57、图2-58。其理论公式为:
g(x)=(1-α)f0(x)+αf1(x)
addWeighted()函数:将2个图像阵列加权求和。
void addWeighted(InputArray src1,double alpha,InputArray src2,double beta,double gamma,OutputArray dst,int dtype=-1);
图2-57
图2-58
第一个参数中填写第一幅需要混合的图像名称;第二个参数表示第一幅图像权重;第三个参数表示第二副图像名称,需要和第一幅拥有相同的尺寸和通道数;第四个参数表示第二幅图像的权重值;第五个参数需要填写输出的图像名称,它的大小和输入的两个图像拥有相同的尺寸和通道数;第六个参数表示一个加到权重总和上的标量值;第七个参数为输出阵列的深度值,默认值为-1。当两个输入图像具有相同的深度时,这个参数设置为-1。
图像线性混合测试程序:
运行以上代码,得到最终融合的效果,如图2-59所示。
图2-59
2.3.4 OpenCV开发实例:边缘识别
在本例中采用霍夫圆变换算法,提取图像中圆的边以及半径。先读取图片,将图片转化为灰度图片。使用HoughCircles()函数不需要使用二值图像作为源图。然后采用高斯低通滤波,平滑图像,去除噪声。使用霍夫圆变换提取零件的边缘及中心,并将边缘和中心在图中绘制出来,效果如图2-60所示。
图2-60