如何查找openCV函数源代码

我们知道openCV是开源的图像处理库,所以我们有时候想查看一下某些关键函数的源码,我常用的方法(针对Visual Studio开发平台)就是右键选择要查找的函数数据类型定义然后在弹出的快捷方式中选择“转到定义”(或“Go to definition”英文版本),这是就可以自动转到函数定义部分。但是,openCV将很多函数被加入了函数库,并被编译成了dll,所以只能看到函数申明,没法看到原始代码。我的解决方法如下:(openCV2.3.1+VS2008)

   1、首先要熟悉openCV安装目录,例如我的安装目录是F:\program files\opencv2.3.1。在这个目录下面还有很多子目录:3rdparty、android、build,data、doc、include、modules、samples和很多cmake文件。对于编程来说,仅仅需要build这一个文件夹就可以了,因为编程环境的配置只与这一个目录有关,如:包含目录配置、库目录配置,具体可以参考http://www.opencv.org.cn/index.php/VC_2008_Express下安装OpenCV2.3.1build目录是编译生成的目录,就是用openCV源代码编译生成的2进制库文件集(dll、lib和入口头文件include)。以下是文档组织结构截图:

如何查找openCV函数源代码

    2、那其他文件夹下的文件都是干嘛用的呢?其实源代码就包含在这些文件夹下面,因为build文件夹就是在其他文件夹的基础上CMake编译生成的。(可以参考CMake编译部分http://www.opencv.org.cn/index.php/VC_2008_Express下安装OpenCV2.3.1)大部分源代码放在modules文件夹下(如下截图)

如何查找openCV函数源代码
例如,core文件夹下就包含了基本数据类型的定义,imgproc文件夹下包含了常用的数字图像处理函数源代码:如cvCanny()、cvSobel()。

3、用CMake导出opencv 源码,生成VC++项目,然后用vs打开工程,去里面搜索整个工程

 

    

如何查看opencv原函数内部实现             

 

原文:http://blog.csdn.net/jfuck/article/details/8665486

对于刚接触opencv的新手来说,利用opencv库函数来实现了某些功能兴奋之余,对其库函数的具体实现更是好奇。仔细读懂opencv的库函数也对函数的用法和限制有了更深入的理解。

    但在VS2010中,在opencv的函数上单击右键后,无论是点“转到定义”或“转到申明”结果都一样,只能跳转到函数对应的头文件中。

            方法一:在opencv的安装文件夹中找到 与头文件名字对应的.C 或 .CPP 文件,然后在对函数进行查找。但不是所用函数都是这样的。例如cvSmooth函数,单击“转到定义”后,其跳转到imgproc_c.h中。通过找到imgproc.c或者imgproc.cpp都没有找到 cvSmooth函数。

            方法二:在VS2010的“编辑”菜单下,点“查找与替换”,然后选“在文件中查找”。对于opencv的源代码,都放在  (安装目录).../opencv/modules 这个文件夹中。将此文件夹添加到查找目录点击查找即可在查找结果中找到函数的实现。

相比之下,方法二更加的简单,有效。

 

OpenCV鼠标交互

一些图像处理算法要求用户的参与,比如分割算法GrabCut需要用户选定初始区域或前/背景掩模,在用OpenCV实现里,就涉及到利用鼠标在图片上选定这些区域,这里讲讲常见的几种鼠标绘图:

1、绘制矩形并获得矩形区域图像:在显示图片的窗口,通过拖动鼠标绘制矩形,按ESC键退出绘图模式。

涉及函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param=NULL );
--window_name
窗口的名字。
--on_mouse
指定窗口里每次鼠标事件发生的时候,被调用的函数指针。
这个函数的原型应该为
--voidFoo(int event, int x,int y, int flags, void* param);
其中event是 CV_EVENT_*变量之一,
x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系),
flags是CV_EVENT_FLAG的组合(即上面的一些有关现在动作状态的预定义,现在鼠标没任何操作时为0),
param是用户定义的传递到cvSetMouseCallback函数调用的参数。
--param
用户定义的传递到回调函数的参数。
函数cvSetMouseCallback设定指定窗口鼠标事件发生时的回调函数。
详细使用方法,请参考opencv/samples/c/ffilldemo.c demo。
#include "cv.h"
#include "highgui.h"

#include <iostream>

using namespace std;
using namespace cv;

void DrawRect(IplImage*img,CvRect rect);
void MouseDraw(int event,int x,int y,int flags,void*param);

struct MouseArgs{
	IplImage* img;
    CvRect box;
	bool Drawing;
	// init
	MouseArgs():Drawing(false),img(0){
		box=cvRect(0,0,-1,-1);
	}
	// destroy
	void Destroy(){
		if(!img)
			cvReleaseImage(&img);
	}
};

int main(int argc, char** argv)
{
	// loading image
	char* imf = argc >= 2 ? argv[1] :"audi-2009.jpg";

	IplImage* pImg_org = cvLoadImage(imf,1);
	if(!pImg_org){
		cout<<"cann't load image!"<<endl;
		return -1;
	}

    // 回调参数
    MouseArgs* m_arg = new MouseArgs();
	m_arg->img = cvCloneImage(pImg_org);

	// 画图窗口
	cvNamedWindow("Draw ROI",CV_WINDOW_AUTOSIZE);

	// 设置鼠标事件的回调函数
	cvSetMouseCallback("Draw ROI",
		MouseDraw,
		(void*)m_arg); 

	// 拖动鼠标作画
	IplImage* temp=cvCloneImage(pImg_org);
	while(1)
	{
		cvCopyImage(m_arg->img,temp);
		if(m_arg->Drawing)
			DrawRect(temp,m_arg->box);
		cvShowImage("Draw ROI",temp);
        // 按 esc 键退出绘图模式,获得矩形
		if(cvWaitKey(100)==27)
			break;

	}
	cvReleaseImage( &temp );  

	// 获得ROI区域的图像
	IplImage*  roi;
	if(m_arg->box.width<10 || m_arg->box.height<10)
	{
		roi=cvCloneImage(pImg_org);
	}
	else
	{
		roi=cvCreateImage(cvSize(m_arg->box.width,m_arg->box.height),
			pImg_org->depth,
			pImg_org->nChannels);
		cvSetImageROI(pImg_org,m_arg->box);//设定ROI
		roi=cvCloneImage(pImg_org);//复制出ROI区域的图像
		cvResetImageROI(pImg_org);

	}

	cvNamedWindow( "ROI", 1 );
	cvShowImage( "ROI", roi );

	//
	cvWaitKey(0);
    cvDestroyWindow("Draw ROI");

	m_arg->Destroy ();
	delete m_arg;
	cvReleaseImage(&pImg_org);
	cvReleaseImage(&roi);
	//
	return 0;

}

/*
描述:在图像上绘制矩形
*/
void DrawRect(IplImage*img,CvRect rect)
{
	cvRectangle(img,
		cvPoint(rect.x,rect.y),
		cvPoint(rect.x+rect.width,rect.y+rect.height),
		cvScalar(255,0,0),3);
}

/*
描述:鼠标事件的回调函数
函数原型:  void Foo(int event, int x, int y, int flags, void* param);
参数: event -- CV_EVENT_*变量之一,
       x,y   -- 鼠标指针在图像坐标系的坐标(不是窗口坐标系)
       flags -- CV_EVENT_FLAG的组合
       param -- 用户定义的传递到cvSetMouseCallback函数调用的参数
*/
void MouseDraw(int event,int x,int y,int flags,void*param)
{
	MouseArgs* m_arg = (MouseArgs*) param;
    if(!m_arg->img)
		return;

	switch(event)
	{
	case CV_EVENT_MOUSEMOVE: // 鼠标移动时
		{
			if(m_arg->Drawing)
			{
				m_arg->box.width = x-m_arg->box.x;
				m_arg->box.height = y-m_arg->box.y;
			}
		}
		break;
	case CV_EVENT_LBUTTONDOWN: // 左键按下
		{
			m_arg->Drawing = true;
			m_arg->box = cvRect(x,y,0,0);
		}
		break;
	case CV_EVENT_LBUTTONUP: // 左键弹起
		{
			m_arg->Drawing = false;
			if (m_arg->box.width<0)
			{
				m_arg->box.x += m_arg->box.width;
				m_arg->box.width *= -1;
			}
			if (m_arg->box.height<0)
			{
				m_arg->box.y += m_arg->box.height;
				m_arg->box.height *= -1;
			}
			DrawRect(m_arg->img, m_arg->box);
		}
		break;
	}
}

2、绘制任意形状并获得区域图像:原理同上,使用CvSeq记录轨迹点,然后用cvFillConvexPoly填充多边形区域形成掩模,最后用cvCopy拷贝区域图像。支持两种绘图模式,描点式(如PS之钢笔)和拖动式:

 

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
  
#include <iostream>
  
usingnamespace std;
usingnamespace cv;
  
structMouseArgs{
    IplImage* img;
    CvPoint p_start;
    CvPoint p_end;
    CvSeq* seq;
    CvMemStorage* storage;
    intpoints;
    // init
    MouseArgs():img(0),points(0){
        p_start = cvPoint(-1,-1);
        p_end = cvPoint(-1,-1);
        storage = cvCreateMemStorage(0);
        seq = cvCreateSeq( CV_32SC2,sizeof(CvSeq),sizeof(CvPoint), storage );
    }
    // destroy
    voidDestroy(){
        if(!img)
            cvReleaseImage(&img);
        cvReleaseMemStorage(&storage );
        seq = NULL;
        img = NULL;
    }
};
  
int main( int argc,char** argv )
{
    // loading image
    char* imf = argc >= 2 ? argv[1] :"audi-2009.jpg";
  
    IplImage* pImg_org = cvLoadImage(imf,1);
    if(!pImg_org){
        cout<<"cann't load image!"<<endl;
        return-1;
    }
  
    // 回调参数
    MouseArgs* m_arg =new MouseArgs();
    m_arg->img = cvCloneImage(pImg_org);
  
    // 画图窗口
    cvNamedWindow("Draw ROI",CV_WINDOW_AUTOSIZE);
  
    // 设置鼠标事件的回调函数
    cvSetMouseCallback("Draw ROI",
        MouseDraw,
        (void*)m_arg); 
  
    // 拖动鼠标作画
    while(1)
    {
        cvShowImage("Draw ROI",m_arg->img);
        // 按 esc 键退出绘图模式,获得矩形
        if(cvWaitKey(100)==27)
            break;
  
    }
  
    // 输出
    if(m_arg->points < 1)
        return0;
    cout<<m_arg->points <<endl;
  
    // 获得掩模
    IplImage* mask = cvCreateImage( cvGetSize(pImg_org), 8, 1 );
    cvZero(mask);
  
    CvPoint* PointArr =new CvPoint[m_arg->points];
    cvCvtSeqToArray(m_arg->seq, PointArr);
    cvFillConvexPoly(mask,PointArr,m_arg->points,cvScalarAll(255),CV_AA,0);
    delete[] PointArr;
    cvNamedWindow("Mask",CV_WINDOW_AUTOSIZE);
    cvShowImage("Mask",mask);
  
    // 获得区域
    IplImage* roi = cvCreateImage( cvGetSize(pImg_org), 8, 3 );
    cvCopy(pImg_org,roi,mask);
    cvNamedWindow("ROI",CV_WINDOW_AUTOSIZE);
    cvShowImage("ROI",roi);
  
    //
    cvWaitKey(0);
    cvDestroyWindow("Draw ROI");
    cvDestroyWindow("Mask");
    cvDestroyWindow("ROI");
  
    //
    m_arg->Destroy ();
    deletem_arg;
    cvReleaseImage(&pImg_org);
    cvReleaseImage(&mask);
    cvReleaseImage(&roi);
    //
    getchar();
    return0;
}
  
// 描点式
/*
void MouseDraw(int event,int x,int y,int flags,void*param)
{
    MouseArgs* m_arg = (MouseArgs*) param;
    if( !m_arg->img )
        return;
  
    if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
    {
        m_arg->p_end = m_arg->p_start;
    }
    else if( event == CV_EVENT_LBUTTONDOWN )
    {
        m_arg->p_start = cvPoint(x,y);
        cvSeqPush( m_arg->seq, &m_arg->p_start);  // 描点记录
        m_arg->points += 1;
        if(m_arg->p_start.x>0 && m_arg->p_end.x>0){
            cvLine( m_arg->img, m_arg->p_start, m_arg->p_end, cvScalar(0,0,255) );
            cvLine( m_arg->img, m_arg->p_start, m_arg->p_start, cvScalar(128,0,255) );
        }
    }
  
}
*/
// 拖动式
voidMouseDraw(intevent,int x,int y,intflags,void*param)
{
    MouseArgs* m_arg = (MouseArgs*) param;
    if( !m_arg->img )
        return;
  
    if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
    {
        m_arg->p_start = cvPoint(x,y);
    }
    elseif( event == CV_EVENT_LBUTTONDOWN )
    {
        m_arg->p_start = cvPoint(x,y);
        cvSeqPush( m_arg->seq, &m_arg->p_start);
        m_arg->points += 1;
        if(m_arg->p_start.x>0 && m_arg->p_end.x>0){
            cvLine( m_arg->img, m_arg->p_start, m_arg->p_start, cvScalar(128,0,255) );
        }
    }
    elseif( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
    {
        CvPoint pt = cvPoint(x,y);
        if( m_arg->p_start.x > 0 ){
            cvLine( m_arg->img, m_arg->p_start, pt, cvScalar(128,0,255) );
            m_arg->p_start = pt;
            cvSeqPush( m_arg->seq, &m_arg->p_start);
            m_arg->points += 1;
        }
  
    }
  
}

 

 

3、鼠标控制动态缩放图像显示:在cvNamedWindow图像窗口中通过“ ALT和鼠标左键开始按下的时候放大图像”和“ALT和鼠标右键开始按下的时候缩小图像”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "cv.h"
#include "highgui.h"
  
#include <iostream>
  
usingnamespace std;
usingnamespace cv;
  
structMouseArgs{
    IplImage* img_src;
    IplImage* img_dst;
    doublescale;
    // init
    MouseArgs():img_src(0),img_dst(0),scale(1.0){
    }
    // destroy
    voidDestroy(){
        if(!img_src)
            cvReleaseImage(&img_src);
        if(!img_dst)
            cvReleaseImage(&img_dst);
    }
};
  
voidMouseResize(intevent,int x,int y,intflags,void*param);
IplImage* resize_img(IplImage* src,doubleimgzoom_scale);
  
int main( int argc,char** argv )
{
    // loading image
    char* imf = argc >= 2 ? argv[1] :"audi-2009.jpg";
  
    IplImage* pImg_org = cvLoadImage(imf,1);
    if(!pImg_org){
        cout<<"cann't load image!"<<endl;
        return-1;
    }
  
    // 回调参数
    MouseArgs* m_arg =new MouseArgs();
    m_arg->img_src = cvCloneImage(pImg_org);
  
    // 画图窗口
    cvNamedWindow("Resize",CV_WINDOW_AUTOSIZE);
  
    // 设置鼠标事件的回调函数
    cvSetMouseCallback("Resize",
        MouseResize,
        (void*)m_arg); 
  
    //
    while(1)
    {
        cvShowImage("Resize",m_arg->img_src);
        // 按 esc 键退出
        if(cvWaitKey(100)==27)
            break;
  
    }
  
    //
    cvWaitKey(0);
    cvDestroyWindow("Resize");
  
    //
    getchar();
    return0;
}
  
voidMouseResize( intevent, int x, int y, int flags, void* param )
{
    MouseArgs* m_arg = (MouseArgs*) param;
    if( !m_arg->img_src )
        return;
  
    if( (event==CV_EVENT_LBUTTONUP) &&  (flags==CV_EVENT_FLAG_CTRLKEY) )
    {
  
    }
  
    // ALT和鼠标左键开始按下的时候放大图像
    if( (event==CV_EVENT_LBUTTONUP) &&  (flags==CV_EVENT_FLAG_ALTKEY) )
    {
  
        if(m_arg->scale<1.5)
        {
            m_arg->scale=1.1*m_arg->scale;
        }
        else
            m_arg->scale=1.0;
  
        // 放大图像
        m_arg->img_dst = resize_img(m_arg->img_src, m_arg->scale);
        m_arg->img_src = cvCloneImage(m_arg->img_dst);
  
    }
  
    //ALT和鼠标右键开始按下的时候缩小图像
    if( (event==CV_EVENT_RBUTTONUP) &&  (flags==CV_EVENT_FLAG_ALTKEY) )
    {
  
        if(m_arg->scale>0.0)
        {
            m_arg->scale=0.9*m_arg->scale;
        }
        else
            m_arg->scale=0.5;
  
        // 缩小图像
        m_arg->img_dst = resize_img(m_arg->img_src, m_arg->scale);
        m_arg->img_src = cvCloneImage(m_arg->img_dst);
  
    }
  
}
  
IplImage* resize_img(IplImage* src,doubleimgzoom_scale)
{
    IplImage* dst = cvCreateImage(cvSize(  (int)(src->width*imgzoom_scale),  (int)(src->height*imgzoom_scale)  ),
        src->depth,
        src->nChannels);
  
    cvResize(src, dst, CV_INTER_AREA );
  
    returndst;
  }

 

 

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值