最近做的一个3D照相馆的项目,其中用到了PCL中的点云处理和OpenCV中的人脸识别,因此需要同时使用PCL和OpenCV两个开源库。于是乎坑爹的问题一个接一个的来了ORZ
一、x64 or win32 ?
这个问题很多新手不是太明白,其实通常情况下我们只需要win32版本的库就可以了。见下图:
右边的那个下拉栏,一般来说选win32就可以了
如下图所示,总共有四种配置的方案,在这里配置的优点是,只要配置一次,下次你新建项目后,就不用再次配置同样的信息了。
下载PCL的时候,建议选择win32的版本
OpenCV的话,在选择引用路径的时候需要注意x86和x64的区别,如图:
其中第一行中的x86说明我们引用的是win32下的lib库。
我的配置是VS2010+PCL1.6.0+OpenCV2.4.9,具体的安装和配置方法网上俯拾即是,我也就不在这里多说了,但是操作这些步骤时一定要小心再小心,一旦有什么闪失,你很难找到问题的所在(被坑过。。。)
二、debug or release ?
一般而言,由于后者的优化,Release下程序的执行效率相对于Debug而言要高一些。就个人经验而谈,在执行一个点云的滤波的时候,debug下执行了半分钟,而release下执行时间只有5秒。那为什么我们还需要debug模式来编码呢?那是因为在release下调试较为困难,很多变量你获取不到当前的值,而debug就可以做到。因此release版本一般是发布版本,debug版本常用于日常的调试。(当然,将release配置中的优化设置为“已禁用”后,运行效率同样会变得很低)
两种不同的配置,对应了两种不同的.lib库。如果你的配置是release,那么在工程的链接器输入中,你需要添加如下的一些.lib:
pcl_tracking_release.lib
pcl_surface_release.lib
pcl_sample_consensus_release.lib
pcl_registration_release.lib
pcl_octree_release.lib
pcl_keypoints_release.lib
pcl_kdtree_release.lib
pcl_io_release.lib
pcl_search_release.lib
pcl_segmentation_release.lib
pcl_apps_release.lib
pcl_features_release.lib
pcl_filters_release.lib
而在debug中,这些链接库则成为了:
pcl_tracking_debug.lib
pcl_surface_debug.lib
pcl_sample_consensus_debug.lib
pcl_registration_debug.lib
pcl_octree_debug.lib
pcl_keypoints_debug.lib
pcl_kdtree_debug.lib
pcl_io_debug.lib
pcl_search_debug.lib
pcl_segmentation_debug.lib
pcl_apps_debug.lib
pcl_features_debug.lib
pcl_filters_debug.lib
pcl_visualization_debug.lib
pcl_common_debug.lib
在OpenCV中同样如此,在我的程序中有这样的写法:
#ifdef _DEBUG
#pragma comment(lib,"opencv_core249d.lib")
#pragma comment(lib,"opencv_highgui249d.lib")
#pragma comment(lib,"opencv_objdetect249d.lib")
#pragma comment(lib,"opencv_imgproc249d.lib")
#pragma comment(lib,"asmlibraryD.lib")
#else
#pragma comment(lib,"opencv_core249.lib")
#pragma comment(lib,"opencv_highgui249.lib")
#pragma comment(lib,"opencv_objdetect249.lib")
#pragma comment(lib,"opencv_imgproc249.lib")
#pragma comment(lib,"asmlibrary.lib")
#endif
这样程序在不同的配置下会自动调用对应的.lib文件了
三、最头疼的问题,flann的冲突问题
记得我一开始是没有使用OpenCV的,程序运行没有什么问题。后来为了添加人脸识别的功能,我添加了OpenCV的函数库,这下问题来了,程序居然跟我说pcl的flann不是有效的命名空间!!于是我在报错处的flann上面按下了F12,源码居然跳转到OpenCV的hpp中去了!!(黑人问号脸)赶紧上网查看了一下,原来在PCL和OpenCV中都有一个叫:flann的namespace(尴尬脸)
该怎么解决呢?网上的搜索到的解决办法很多,但基本就是一种,那就是将pcl的引用调整到opencv的前面,然后不使用using namespace cv;并在所有的cv空间下的类型前加上“cv::”看上去挺有道理的,但我试了下,发现还是不行。
于是在上述的操作之后,我另辟蹊径,做了如下的更改:
进入自己的openCV安装路径下,找到opencv2这个文件夹,然后将flann改为flann2(见下图)
然后选择“组织”,选择“文件夹和搜索选项”,如下图
选择“始终搜索文件名和内容”,并确定即可,如下图
然后返回上一层(注意要返回上一层!)并在右上角搜索“opencv2/flann/”,这样就可以找到所有包含有搜索字符串的文件了,这样我们搜索到如下几个结果(不同版本的opencv,这里的数量可能不一样,这个我就不太清楚了):
进入这5个文件,将所有“opencv2/flann/”修改为“opencv2/flann2/”,如图所示:
全部处理完成后,flann冲突的问题就解决了,程序应当可以正常编译运行了。同时OpenCV的使用也不会受到影响^_^
四、release和debug的.lib文件的顺序问题(血的教训!)
我为了图省事,在debug和release两种配置的链接库里,将所有的.lib文件,不分debug和release地全部添加了进去,结果在debug下运行的时候,发现怎么都读取不了.pcd点云的数据,而release下就没有问题。我找啊找,找啊找,最后终于发现,原来我的所有的release的lib文件都是在debug的lib前面,如下图所示:
注意千万不要这么用!!因为release下的lib在前,因此会屏蔽掉debug下的lib。所以最好的解决方案就是debug配置下只是用debug的lib,release配置下只使用release下的lib。
五、补充的一个问题
这个问题可能遇到的人不多,但是既然我遇到了,那就记录在这里吧。
在使用opencv时提示我系统丢失了MSVCRTD.DLL文件,那好,我就在网上下载了一个,并复制到sysWow64文件夹中。但是这么一来,我在debug下运行时又出现了“windows 已在….exe中触发了一个断点,其原因可能是堆损坏,这说明…中或它加载的任何dll中有bug……”这种问题,我猜可能是我下载的dll文件有点小问题,我的解决办法是将项目的静态编译调整为共享dll编译,就可以正常运行了。
当然这是个治标不治本的方法,如果以后找到了更好的方法再贴出来。