首页 > 代码库 > 如何修改调试OpenCV源码

如何修改调试OpenCV源码

        有时候,直接调用OpenCV的接口并不能满足我们的需求,需要我们对源码及其算法进行修改。这里就介绍一下如何修改OpenCV的源码。首先,要用cmake编译一下OpenCV;然后,就是修改源码了;接着,配置新生成的dll和lib;最后,测试。


一、cmake编译OpenCV

     

  1、下载安装cmake

想要在Windows平台下生成OpenCV的解决方案,我们需要一个名为cmake的开源软件,可以在

camke的官网:http://www.cmake.org/上下载到,首先转到其下载页面。

而Binary distributions处可以下载到cmake的执行文件,我们只需要下载到其执行文件即可,选择Windows (Win32 Installer)进行下载,点击这里直接下载:http://www.cmake.org/files/v2.8/cmake-2.8.12.2-win32-x86.exe

这一步就是下载和安装cmake,下载地址给出了,安装大家都会,就不过多讲。安装完成后,

如果没有生成桌面快捷方式,在安装路径下,如D:\Program Files(x86)\CMake 2.8\bin处找到cmake-gui.exe运行



  2、使用cmake生成OpenCV源代码工程的解决方案
这一步,参考了 浅墨  的博文【有区别】

<1>运行cmake-gui

如果没有生成桌面快捷方式,在安装路径下,如D:\Program Files(x86)\CMake 2.8\bin处找到cmake-gui.exe运行。技术分享


<2>指定OpenCV的安装路径

如下图,点击红色方框内的“Browse Source”按钮,在弹出的对话框中指定出OpenCV安装时源代码的存储路径。

以当前最新版本的OpenCV 2.4.8安装在D:\Program Files下为例,则在此选择路径:D:\Program Files\opencv\sources

其实我们可以发现,此路径下必须会有一个名为CMakeLists.txt的文件。

         技术分享

这个文件就是给cmake留下的配置文件,cmake可以根据这个配置文件,通过不同的编译器选择,来生成不同的解决方案,VisualStudio的编译器对应的就生成Visual Studio版的sln解决方案。


<3>指定解决方案的存放路径

点击红色方框内的“Browse Build”按钮,在弹出的对话框中指定我们存放生成的opencv解决方案的路径。比如F:/opencv。


<4>第一次Configure

第一次点击Configure按钮。会弹出编译器选择的对话框;

首先选定“Use default native compilers”,然后,我们可以发现下拉列表中提供了几十种编译器给我们选择,因为我们安装了Visual Studio,会默认为我们选择好对应版本的Visual Studio编译器,比如Visual Studio 10(即待会儿会生成对应VS2010的sln解决方案)

确认无误后,单击“finish”按钮。


<5>第二次Configure

第一次配置完成之后,我们还需要进行第二次配置,于是再次点击“Configure”按钮。这次的配置是很快的,几秒钟就会再次出现“Configuring done”字样,并且红色的选中部分都正常了。


<6>点击Generate,大功告成

这样,就只剩下点一次Generate按钮,来生成最终的解决方案了。因为之前已经有过两次的configure过程,所以生成解决方案也将是非常的快。看到Generating done字样,就表示大功告成,可以去之前我们指定的F:\opencv下找寻我们生成的解决方案了。

PS:自从2.4.7版本起,opencv源代码就直接包含在了opencv的安装路径下,我们生成的sln工程,也只是连接到了opencv安装路径下的源文件而已,工程本身并不大。


 3、编译OpenCV源代码

      (1)打开刚刚生成的热乎乎的“OpenCV.sln”解决方案,看到一个庞大的工程映入眼帘——这可是一个包含了68个项目的解决方案:

技术分享


  

   (2)右击图中的INSTALL,点击生成。然后点击debug的开始按钮。

 然后再release下也进行一遍。

编译用时5分钟左右,具体时间和机器配置关系比较大。另外,编译完成会得到这样的警告:

技术分享

别紧张,这是正常的。因为OpenCV2.4.8的源代码工程默认将“ALL_BUILD”这个项目其设为了启动项,编译成功后,就会默认运行它。

技术分享

而“ALL_BUILD”是一个项目生成周边的杂项,不是exe,本身不可以运行,所以就会弹出这样的提示。

 

      【PS】:

        1)关于启动项的指定,我们可以在解决方案资源管理器里面,对需要设为启动项的那个项目反键点击,在弹出的菜单项中点击【设为启动         项(J)】进行设定。如下图:

技术分享


     2)编译OpenCV,就是得到了一些二进制的生成文件,如DLL和Lib、exe。位于install目录下。该目录下的文件很重要。

技术分享


    3)进入install目录后有很多文件。下面简要说明:

A、include目录:头文件

B、x86目录:而在lib目录下则是生成的各个模块的lib。Lib只是Dll的附带品,是DLL导出的函数列表文件而已

  

  4、配置OpenCV编译环境

环境变量path应该添加以下两个路径:

D:\program tool\opencv\VS2010_OpenCV\VS2010_Solution\install\x86\vc10\bin

注:D:\program tool\opencv\VS2010_OpenCV\VS2010_Solution\install\x86\vc10\bin 是用CMake生成的VS2010工程的所在目录。

说明:之前用的是OpenCV自带编译版本的请注意了,应该将原来环境变量删除后再添加。一开始没有删除导致后面一直调试不成功,即使能跟踪源代码了,但是只要函数形参是const string& 的函数,字符串就无法正常传递,调试时发现函数形参一直是<错误的指针>,无法赋值。具体原因不太懂。


   5、新建OpenCV工程

1、打开VS2012,新建控制台应用程序TestOpencv。

2、配置包含目录和库目录

添加新项目属性表

                 技术分享

右击—— 属性->VC++目录->包含目录,添加

    D:\program tool\opencv\VS2010_OpenCV\VS2010_Solution\install\include 

    D:\program tool\opencv\VS2010_OpenCV\VS2010_Solution\install\include\opencv2

     D:\program tool\opencv\VS2010_OpenCV\VS2010_Solution\install\include\opencv                                                                          

属性->VC++目录->库目录,添加

     D:\program tool\opencv\VS2010_OpenCV\VS2010_Solution\install\x86\vc10\lib

注意:这些目录都是cmake生成的。(release下同样)

release下还应进行以下配置,选择多线程DLL(/MD),否则运行会出错。

技术分享


3、添加附加依赖项

在 链接器->输入->附加依赖项处添加:

opencv_ml249d.lib
opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_objdetect249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_nonfree249d.lib
opencv_ocl249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_superres249d.lib
opencv_videostab249d.lib
opencv_objdetect249.lib
opencv_ts249.lib
opencv_video249.lib
opencv_nonfree249.lib
opencv_ocl249.lib
opencv_photo249.lib
opencv_stitching249.lib
opencv_superres249.lib
opencv_videostab249.lib
opencv_calib3d249.lib
opencv_contrib249.lib
opencv_core249.lib
opencv_features2d249.lib
opencv_flann249.lib
opencv_gpu249.lib
opencv_highgui249.lib
opencv_imgproc249.lib
opencv_legacy249.lib
opencv_ml249.lib

【注】  要将debug与release下的lib分开添加,不然会出现imread无法读取数据的问题

二、修改源码

(本人使用的是OpenCV2.4.9)

1、比如我想修改imshow()函数,使其显示图像的同时输出我们自己加的tfygg modify 这句话。我们找opencv_highgui模块中的window.cpp文件的257行,并修改为:

void cv::imshow( const string& winname, InputArray _img )
{
	std::cout<<"-----------------------------------华丽分隔符----------------------------------"<<std::endl;
	std::cout<<"tfygg modify!"<<std::endl;
	std::cout<<"-----------------------------------华丽分隔符----------------------------------"<<std::endl;
    const Size size = _img.size();
...
}
然后,加上头文件 #include<iostream>

修改完,直接在opencv_highgui项目右击点生成。


三、更新include目录方法

如果要添加函数的话,要注意两点:

(1)应在配置路径中的include目录下添加相应的函数声明;

(2)重新编译dll,lib


四、测试

我们知道BackgroundSubtractorMOG类中的没有背景提取方法,这里为其添加getBackgroundImage()方法。

/*------------------------------------------------------------------------------------------*  Author: tfygg
  Date: 2015.12.4
\*------------------------------------------------------------------------------------------*/

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>

int main()
{
	// Open the video file
    cv::VideoCapture capture("bike.avi");
	// check if video successfully opened
	if (!capture.isOpened())
		return 0;

	// current video frame
	cv::Mat frame; 
	// foreground binary image
	cv::Mat foreground;
	cv::Mat background;

	cv::namedWindow("Extracted Foreground");

	// The Mixture of Gaussian object
	// used with all default parameters
	cv::BackgroundSubtractorMOG mog;

	bool stop(false);
	// for all frames in video
	while (!stop) {

		// read next frame if any
		if (!capture.read(frame))
			break;

		// update the background
		// and return the foreground
		mog(frame,foreground,0.01);
		mog.getBackgroundImage(background);
		// Complement the image
		//cv::threshold(foreground,foreground,128,255,cv::THRESH_BINARY_INV);

		// show foreground
		cv::imshow("Extracted Foreground",foreground);

		cv::imshow("background",background);
		// introduce a delay
		// or press key to stop
		if (cv::waitKey(10)>=0)
				stop= true;
	}

	cv::waitKey();
}



测试结果:
技术分享


 技术分享

如何修改调试OpenCV源码