学习OpenCV第0天

自2011年接触OpenCV已经有几年了,一直停留在写一些小程序,利用手册完成一些任务,一直没有深入研究其中代码,如今毕业,但各种原因未能进入图像处理行业,故现重学OpenCV,包括分析代码,学习算法,blog不定时更写,欢迎交流。

搭建环境:VS2010+CV1.0

最新CV是3.0 alpha,但1.0结构简单,基础功能还是有的,而且本人比较熟悉C语言,故选择1.0。

官网下载1.0的安装文件,系统自动安装到C:\Program Files (x86),进入OpenCV目录,会发现有一个C:\Program Files (x86)\OpenCV\_make目录,里面有一个OpenCV.sln文件,这个很好辨认,用vs2010打开文件,因为是2008的工程文件,所以需要转换,还好没有报错,直接生成工程,使用Debug版本,因为原版是Release的,无法单步调试。

生成项目后,会在相应目录下看到文件名为d结尾的lib和dll,根据Vs配置OpenCV的原理(网上有很多,不再赘述),至此环境完成,只要新建项目,单步调试,就能一步步的观察函数的内部结构。

#include <cv.h>
#include <highgui.h>

int main()
{
	IplImage * image = cvLoadImage("e:\\1.jpg",1);

	cvNamedWindow("原图");
	cvNamedWindow("变换");
	cvShowImage("原图",image);
	cvSmooth(image,image,CV_GAUSSIAN,3,3,0,0);
	cvShowImage("变换",image);
	cvWaitKey();
	cvDestroyWindow("原图");
	cvDestroyWindow("变换");
	cvReleaseImage(&image);
	return 0;
}

调试的话进入cvSmooth:

CV_IMPL void
cvSmooth( const void* srcarr, void* dstarr, int smooth_type,
          int param1, int param2, double param3, double param4 )
{
    CvBoxFilter box_filter;
    CvSepFilter gaussian_filter;

    CvMat* temp = 0;

    CV_FUNCNAME( "cvSmooth" );

    __BEGIN__;

    int coi1 = 0, coi2 = 0;
    CvMat srcstub, *src = (CvMat*)srcarr;
    CvMat dststub, *dst = (CvMat*)dstarr;
    CvSize size;
    int src_type, dst_type, depth, cn;
    double sigma1 = 0, sigma2 = 0;
    bool have_ipp = icvFilterMedian_8u_C1R_p != 0;

    CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
    CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));

    if( coi1 != 0 || coi2 != 0 )
        CV_ERROR( CV_BadCOI, "" );

    src_type = CV_MAT_TYPE( src->type );
    dst_type = CV_MAT_TYPE( dst->type );
    depth = CV_MAT_DEPTH(src_type);
    cn = CV_MAT_CN(src_type);
    size = cvGetMatSize(src);

    if( !CV_ARE_SIZES_EQ( src, dst ))
        CV_ERROR( CV_StsUnmatchedSizes, "" );

    if( smooth_type != CV_BLUR_NO_SCALE && !CV_ARE_TYPES_EQ( src, dst ))
        CV_ERROR( CV_StsUnmatchedFormats,
        "The specified smoothing algorithm requires input and ouput arrays be of the same type" );

    if( smooth_type == CV_BLUR || smooth_type == CV_BLUR_NO_SCALE ||
        smooth_type == CV_GAUSSIAN || smooth_type == CV_MEDIAN )
    {
        // automatic detection of kernel size from sigma
        if( smooth_type == CV_GAUSSIAN )
        {
            sigma1 = param3;
            sigma2 = param4 ? param4 : param3;

            if( param1 == 0 && sigma1 > 0 )
                param1 = cvRound(sigma1*(depth == CV_8U ? 3 : 4)*2 + 1)|1;
            if( param2 == 0 && sigma2 > 0 )
                param2 = cvRound(sigma2*(depth == CV_8U ? 3 : 4)*2 + 1)|1;
        }

        if( param2 == 0 )
            param2 = size.height == 1 ? 1 : param1;
        if( param1 < 1 || (param1 & 1) == 0 || param2 < 1 || (param2 & 1) == 0 )
            CV_ERROR( CV_StsOutOfRange,
                "Both mask width and height must be >=1 and odd" );

        if( param1 == 1 && param2 == 1 )
        {
            cvConvert( src, dst );
            EXIT;
        }
    }

    if( have_ipp && (smooth_type == CV_BLUR || smooth_type == CV_MEDIAN) &&
        size.width >= param1 && size.height >= param2 && param1 > 1 && param2 > 1 )
    {
        CvSmoothFixedIPPFunc ipp_median_box_func = 0;

        if( smooth_type == CV_BLUR )
        {
            ipp_median_box_func =
                src_type == CV_8UC1 ? icvFilterBox_8u_C1R_p :
                src_type == CV_8UC3 ? icvFilterBox_8u_C3R_p :
                src_type == CV_8UC4 ? icvFilterBox_8u_C4R_p :
                src_type == CV_32FC1 ? icvFilterBox_32f_C1R_p :
                src_type == CV_32FC3 ? icvFilterBox_32f_C3R_p :
                src_type == CV_32FC4 ? icvFilterBox_32f_C4R_p : 0;
        }
        else if( smooth_type == CV_MEDIAN )
        {
            ipp_median_box_func =
                src_type == CV_8UC1 ? icvFilterMedian_8u_C1R_p :
                src_type == CV_8UC3 ? icvFilterMedian_8u_C3R_p :
                src_type == CV_8UC4 ? icvFilterMedian_8u_C4R_p : 0;
        }

        if( ipp_median_box_func )
        {
            CvSize el_size = { param1, param2 };
            CvPoint el_anchor = { param1/2, param2/2 };
            int stripe_size = 1 << 14; // the optimal value may depend on CPU cache,
                                       // overhead of the current IPP code etc.
            const uchar* shifted_ptr;
            int y, dy = 0;
            int temp_step, dst_step = dst->step;

            CV_CALL( temp = icvIPPFilterInit( src, stripe_size, el_size ));

            shifted_ptr = temp->data.ptr +
                el_anchor.y*temp->step + el_anchor.x*CV_ELEM_SIZE(src_type);
            temp_step = temp->step ? temp->step : CV_STUB_STEP;

            for( y = 0; y < src->rows; y += dy )
            {
                dy = icvIPPFilterNextStripe( src, temp, y, el_size, el_anchor );
                IPPI_CALL( ipp_median_box_func( shifted_ptr, temp_step,
                    dst->data.ptr + y*dst_step, dst_step, cvSize(src->cols, dy),
                    el_size, el_anchor ));
            }
            EXIT;
        }
    }

    if( smooth_type == CV_BLUR || smooth_type == CV_BLUR_NO_SCALE )
    {
        CV_CALL( box_filter.init( src->cols, src_type, dst_type,
            smooth_type == CV_BLUR, cvSize(param1, param2) ));
        CV_CALL( box_filter.process( src, dst ));
    }
    else if( smooth_type == CV_MEDIAN )
    {
        if( depth != CV_8U || cn != 1 && cn != 3 && cn != 4 )
            CV_ERROR( CV_StsUnsupportedFormat,
            "Median filter only supports 8uC1, 8uC3 and 8uC4 images" );

        IPPI_CALL( icvMedianBlur_8u_CnR( src->data.ptr, src->step,
            dst->data.ptr, dst->step, size, param1, cn ));
    }
    else if( smooth_type == CV_GAUSSIAN )
    {
        CvSize ksize = { param1, param2 };
        float* kx = (float*)cvStackAlloc( ksize.width*sizeof(kx[0]) );
        float* ky = (float*)cvStackAlloc( ksize.height*sizeof(ky[0]) );
        CvMat KX = cvMat( 1, ksize.width, CV_32F, kx );
        CvMat KY = cvMat( 1, ksize.height, CV_32F, ky );

        CvSepFilter::init_gaussian_kernel( &KX, sigma1 );
        if( ksize.width != ksize.height || fabs(sigma1 - sigma2) > FLT_EPSILON )
            CvSepFilter::init_gaussian_kernel( &KY, sigma2 );
        else
            KY.data.fl = kx;

        if( have_ipp && size.width >= param1*3 &&
            size.height >= param2 && param1 > 1 && param2 > 1 )
        {
            int done;
            CV_CALL( done = icvIPPSepFilter( src, dst, &KX, &KY,
                        cvPoint(ksize.width/2,ksize.height/2)));
            if( done )
                EXIT;
        }

        CV_CALL( gaussian_filter.init( src->cols, src_type, dst_type, &KX, &KY ));
        CV_CALL( gaussian_filter.process( src, dst ));
    }
    else if( smooth_type == CV_BILATERAL )
    {
        if( param1 < 0 || param2 < 0 )
            CV_ERROR( CV_StsOutOfRange,
            "Thresholds in bilaral filtering should not bee negative" );
        param1 += param1 == 0;
        param2 += param2 == 0;

        if( depth != CV_8U || cn != 1 && cn != 3 )
            CV_ERROR( CV_StsUnsupportedFormat,
            "Bilateral filter only supports 8uC1 and 8uC3 images" );

        IPPI_CALL( icvBilateralFiltering_8u_CnR( src->data.ptr, src->step,
            dst->data.ptr, dst->step, size, param1, param2, cn ));
    }

    __END__;

    cvReleaseMat( &temp );
}

时间: 2024-11-29 07:12:08

学习OpenCV第0天的相关文章

【从零学习openCV】IOS7人脸识别实战

前言 接着上篇<IOS7下的人脸检測>,我们顺藤摸瓜的学习怎样在IOS7下用openCV的进行人脸识别,实际上非常easy,因为人脸检測部分已经完毕,剩下的无非调用openCV的方法对採集到的人脸样本进行训练,终于得到一个能够预測人脸的模型.可是当中的原理可谓是博大精深,因为快临最近末考试了,没时间去琢磨当中详细的细节,这次就先写个大概的demo,下次更新文章就得到6月20号之后了. 原理: 从OpenCV2.4之后,openCV增加了新的类FaceRecognizer,我们能够使用它便捷地进

学习Opencv 2.4.9 (一)---Opencv + vs2012环境配置

作者:咕唧咕唧liukun321 来自:http://blog.csdn.net/liukun321 首先获得最新的Opencv 2.4.9源码:opencv源码下载 一.Opencv环境变量配置 1.将源码安装到制定目录: 2.为Opencv 添加环境变量:计算机-->属性 点击高级系统设置 3.出来系统属性对话框后,点击环境变量. 4.弹出如下对话框:选中PATH 单击新建 5.点击新建添加环境变量 6.将opencv2.4.9变量包含到PATH中去 二.然后再看VS2012 的配置. 1.

《学习opencv》笔记——矩阵和图像操作——cvGEMM,cvGetCol,cvGetCols and cvGetDiag

矩阵和图像的操作 (1)cvGEMM函数 其结构 double cvGEMM(//矩阵的广义乘法运算 const CvArr* src1,//乘数矩阵 const CvArr* src2,//乘数矩阵 double alpha,//1号矩阵系数 const CvArr* src3,//加权矩阵 double beta,//2号矩阵系数 CvArr* dst,//结果矩阵 int tABC = 0//变换标记 ); tABC变换标记及其对应的含义 CV_GEMM_A_T 转置 src1 CV_GE

学习OpenCV的学习笔记系列(三)显示图片及视频

OpenCV是计算机视觉库,那么处理的对象无非两个:"图片"及"视频"(其实视频也是被解压成单帧图像来处理的,总的来说,还是处理图像). 那么要想学习OpenCV,第一步必须知道OpenCV是怎么打开"图像"及"视频"文件然后显示的. 如果要想实现这些功能,其实很简单,步骤如下: 1. 新建工程 打开VS2010,新建一个项目,选择"Win32控制台应用程序"(使用控制台可以省掉很多麻烦),取名"

学习OpenCV研究报告指出系列(二)源代码被编译并配有实例project

下载并安装CMake3.0.1 要自己编译OpenCV2.4.9的源代码.首先.必须下载编译工具,使用的比較多的编译工具是CMake. 以下摘录一段关于CMake的介绍: CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描写叙述全部平台的安装(编译过程).他可以输出各种各样的makefile或者project文件,能測试编译器所支持的C 特性,类似UNIX下的automake.仅仅是 CMake 的组态档取名为 CmakeLists.txt.Cmake 并不直接建构出终于的软件,而是

《学习opencv》笔记——矩阵和图像操作——cvDet,cvDit,cvDotProduct,cvEigenVV and cvFlip

矩阵和图像的操作 (1)cvDet函数 其结构 double cvDet(//计算矩阵的行列式 const CvArr* mat ); 实例代码 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <iostream> using namespace std; int main() { double va[] = {1,0,0,0,2,0,0,0,3}; CvMat Va=cvMa

VS 2008 和 OpenCV 2.0 环境搭配[转]

前几天,老大给我 OpenCV 的资料,让咱几个先学着,说是可能会有个 OpenCV 的项目要做, 呵呵,自然,我们又是一番学习咯,一开始当然就是搭环境咯, 其实 OpenCV 和 VS 2008 的集成开发环境是非常容易搭建的, 在网上资料也有很多很多,而我这里也只是拿着别个的东西整理一下而已, 这一次,由于搭配环境是没什么技术含量的事情,所以,并不会使用过多的文字来描述整个过程, 反而我选择以贴图片的形式提供信息,下面为了介绍详细同时顾及到生手的缘故,将会贴出比较多的图片, 有一些图片也是废

《学习opencv》笔记——矩阵和图像操作——cvSetIdentity,cvSolve,cvSplit,cvSub,cvSubS and cvSubRS

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

《学习opencv》笔记——矩阵和图像操作——cvAdd、cvAddS and cvAddWeighted

矩阵和图像的操作 (1)cvAdd函数 其结构 void cvAdd(//图像加和 const CvArr* src1,//第一个原矩阵 const CvArr* src2,//第二个原矩阵 CvArr* dst, //存放矩阵 const CvArr* mask = NULL: //控制点 ); 就是单纯的将两个图像加和,mask变量控制加和的元素点,相当于"开关的作用"; 程序实例 #include <cv.h> #include <highgui.h> #