版权声明:本文为博主原创文章,未经博主允许不得转载。
尽管之前写过一篇关于OpenCV的介绍,但依然有朋友对其不甚了解。所以,经常能碰到有人问我诸如以下一些问题:OpenCV能不能实现人脸识别?OpenCV有没有车辆检测的API?OpenCV有没有三维重建的函数?面对这样的问题,我也很困惑。到底该如何给他们解释,才能让它们明白,OpenCV确实很强大,但还没有他们想象中的那么强大。其实,OpenCV的全称,是Open source Computer Vision Library,开放源代码计算机视觉库。也就是说,它是一套关于计算机视觉的开放源代码的API函数库。这也就意味着,(1)不管是科学研究,还是商业应用,都可以利用它来作开发;(2)所有API函数的源代码都是公开的,你可以看到其内部实现的程序步骤;(3)你可以修改OpenCV的源代码,编译生成你需要的特定API函数。但是,作为一个库,它所提供的,仅仅是一些常用的,经典的,大众化的算法的API。一个典型的计算机视觉算法,应该包含以下一些步骤:(1)数据获取(对OpenCV来说,就是图片);(2)预处理;(3)特征提取;(4)特征选择;(5)分类器设计与训练;(6)分类判别;而OpenCV对这六个部分,分别(记住这个词)提供了API。下面我分别就这六个部分对一些常见问题进行必要的解释。
对于数据获取,计算机视觉领域的数据,无非就是图片和视频两种。图片,有bmp,jpg,png,tiff....各种压缩和非压缩格式。所以,对压缩格式的图片而言,OpenCV内部必然包含了对应的图片解压缩函数(一般都是包含了开源的图片解压函数库,例如,对于jpg压缩格式而言,就包含了libjpg开源库)。而对于视频而言,常见的有.rmvb,.avi,.asf等格式,不同的格式,代表着不同的视频压缩算法(对于AVI格式,尽管都是avi格式,但内部的压缩算法仍然不相同。具体原因请参考我的另一篇博客:,也就需要对应的解压算法来解压。尽管OpenCV提供了一些读写视频文件的API,但是,它也仅仅是一个接口而已,其内部,依然需要调用相应的视频编解码器的API来进行解码。常用的视频编解码器有:xvid,ffmpeg等。也就是说,如果你想利用OpenCV来进行视频读写之类的操作,是需要安装此类视频编解码器的。安装了相应的视频解码器之后,你就可以调用OpenCV的视频相关API来进行视频文件的读取操作了,当然,视频文件被解码之后,变成了一张一张的图片,然后才能被OpenCV所处理。另外,还有一种情况,就是数据来自于相机,包括数字相机和模拟相机。不管是哪种相机,你都要想办法获取到相机发送给PC的图片数据(PC在内存里面接收到的来自相机的数据可能是jpg格式,也可能是bmp格式)。如果,你在PC内存中接收到的是相机发送过来的jpg压缩格式,还需要进行图片数据的内存解压。
对于预处理,一般就是去除或者降低噪声,光照归一化,亮度归一化,模糊化,锐化,膨胀,腐蚀、开闭等这些操作(详见,冈萨雷斯,《数字图像处理》一书)。而对于这些操作,OpenCV分别(又提到这个词了)提供了相应API函数。而光照的预处理,OpenCV提供了一个直方图均衡化的API,后续可能会提供一些gammar矫正之类的函数。
文章,自然就知道了。
对于特征选择,OpenCV并没有提供特定的函数来进行衡量。而特征的分类能力的高低评价,有很多种分析方法,有兴趣的朋友,可以阅读"《机器学习》Tom. Mitchell(著),曾华军(译),机械工业出版社"这本书;
对于分类器部分,OpenCV提供了SVM,CART,boost,bayes,bdt,ANN,这几种常用的算法。而这些基本已经覆盖了常用的分类器。所以,你需要做的,就是知道怎么调用其接口,各种分类器的优点和缺点(该部分,建议阅读“机器学习”这本书)。
文章了。然后,根据这些文章中阐述的原理和方法,来编程实现你要的东西。实际上,也就等于搭建一个属于你私有的积木块。其实,OpenCV中的每一个API函数,也就是这么来的。
Mat temp;
CvMat tmp;
void gamma_correct(Mat& img, Mat& dst, double gamma) {
img.convertTo(temp, CV_32FC1, 1.0/255.0, 0.0);
tmp=temp;
cvPow(&tmp, &tmp, gamma);
temp.convertTo(dst , CV_8UC1 , 255.0 , 0.0);
}