解析icvLoadImage函数

看一下icvLoadImage这个函数

view plaincopy to clipboardprint?
/*-----------------------------------------------------------------
 *虽然根据参数来说有不同的返回数据的方式,一种是IplImage*,一种是矩阵
 *的形式,但是实际上而言,内部数据都是通过矩阵在存储,所以这里就不用
 *再分两个函数:一个返回IplImage*,一个返回Cmat*。直接返回void*
 *---------------------------------------------------------------*/
static void*
icvLoadImage( const char* filename, int flags, bool load_as_matrix )
{
    GrFmtReader* reader = 0; //读取器指针。
    IplImage* image = 0;     //返回图片数据指针。具体结构可以见前面。
    CvMat hdr, *matrix = 0;  //两个参数应该是与从矩阵中读入是相关的。
    int depth = 8;

    CV_FUNCNAME( "cvLoadImage" ); //主要是用于处理报错用的。可以不看。

    __BEGIN__;                //就是一个宏:定义为{所以这行也可以没有

    CvSize size;              //大小的struct :可以看一下后面的定义:
    int iscolor;              //如何取颜色的变量.
    int cn;
//看一下文件是否为空.有两方面要考虑:指针为空,内容为空。
    if( !filename || strlen(filename) == 0 )
        CV_ERROR( CV_StsNullPtr, "null filename" );
//g_Filters是LoadSave.cpp文件中的一个静态变量,因为可以重
//复读取一些图片,但是读取图像的接口是不变的,那么在构造好
//之后,就可以不再重复构造。
//reader指向读取图像的处读取器。     
    reader = g_Filters.FindReader( filename );
    if( !reader )     //如果没有找到。
        EXIT;
//主要是读取文件头。得到一些基本的信息。
    if( !reader->ReadHeader() )
        EXIT;
//设置大小。
    size.width = reader->GetWidth();
    size.height = reader->GetHeight();
//这里如果flags是-1,那么在读取的时候就用文件本身的通道数。
    if( flags == -1 )
        iscolor = reader->IsColor();
    else
    {
//每个宏的值可以后面看一下:
//3信道
//(CV_LOAD_IMAGE_COLOR),
//单信道
//(CV_LOAD_IMAGE_GRAYSCALE),
//保持不变
//(CV_LOAD_IMAGE_ANYCOLOR)
//深度指定输入的图像是否转为每个颜色信道每象素8位,或者同输入的图像一样保持不变。
//8位无符号,16位无符号,32位有符号或者32位浮点型。
//CV_LOAD_IMAGE_ANYDEPTH
//如果输入有冲突的标志,将采用较小的数字值
//CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYCOLOR = CV_LOAD_IMAGE_COLOR
//CV_LOAD_IMAGE_ANYCOLOR和CV_LOAD_IMAGE_UNCHANGED是等值的。
//CV_LOAD_IMAGE_ANYCOLOR有着可以和CV_LOAD_IMAGE_ANYDEPTH同时使用的优点,
//所以CV_LOAD_IMAGE_UNCHANGED不再使用了。
//载入最真实的图像,选择CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR。
        if( (flags & CV_LOAD_IMAGE_COLOR) != 0 ||
           ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && reader->IsColor()) )
            iscolor = 1;
        else
            iscolor = 0;

        if( (flags & CV_LOAD_IMAGE_ANYDEPTH) != 0 )
        {
            reader->UseNativeDepth(true);
            depth = reader->GetDepth();
        }
    }
//就是看一下是用3色图,还是灰度图。
    cn = iscolor ? 3 : 1;

    if( load_as_matrix )           //如果是从矩阵读入
    {
        int type;    //设置一下读数据,看一下是不是浮点数.
        if(reader->IsFloat() && depth != 8)
            type = CV_32F;
        else   //如果每一个的数较小,那么往8的倍数上取。
            type = ( depth <= 8 ) ? CV_8U : ( depth <= 16 ) ? CV_16U : CV_32S;
    //建立一个矩阵.注意一下CV_CALL
        CV_CALL( matrix = cvCreateMat( size.height, size.width, CV_MAKETYPE(type, cn) ));
    }
    else
    {
        int type;                   //设置一下是不是读入浮点数.
        if(reader->IsFloat() && depth != 8)
            type = IPL_DEPTH_32F;
        else         //往8的倍数上取.
            type = ( depth <= 8 ) ? IPL_DEPTH_8U : ( depth <= 16 ) ? IPL_DEPTH_16U : IPL_DEPTH_32S;
           //建立一个图片。
        CV_CALL( image = cvCreateImage( size, type, cn ));
    //把数据矩阵设置好。尽管这里返回值不是矩阵的形式,
    //其内部结构应该就是一个矩阵。
        matrix = cvGetMat( image, &hdr );
    }
    //把数据读入到矩阵中.如果读取失败,那么就释放数据。
    if( !reader->ReadData( matrix->data.ptr, matrix->step, iscolor ))
    {      
        if( load_as_matrix )
            cvReleaseMat( &matrix );
        else
            cvReleaseImage( &image );
        EXIT;
    }

    __END__;

    delete reader;                  //用的是delete,看来应该是前面读取器的复制。
                                          //看一下状态,有没有出错的状态。
    if( cvGetErrStatus() < 0 )
    {
        if( load_as_matrix )
            cvReleaseMat( &matrix );
        else
            cvReleaseImage( &image );
    }
           //根据不同的情况返回不同的值。
    return load_as_matrix ? (void*)matrix : (void*)image;
}
 

这里应该就是大致辞看了一下这个函数的读取的过程。

其实里面应该还有一很多细节,那么这里从头开始往下讲。

遇到的第一个数据结构就是GrFmtReader ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值