cvCreateImage与cvCreateImageHeader区别和使用

1. cvCreateImage使用方法


1.1功能:创建图像首地址,并分配存储空间。

IplImage* cvCreateImage(CvSize cvSize(int width, int height), int depth, int channels);
参数说明:
1.CvSize cvSize(int width, int height):图像的宽度和高度
2.int depth:图像像素的位深度
值为可以为下面几种:

代码 含义
IPL_DEPTH_8U 8位无符号整数
IPL_DEPTH_8S 8位符号整数
IPL_DEPTH_16U 16位无符号整数
IPL_DEPTH_16S 16位符号整数
IPL_DEPTH_32S 32位符号整数
IPL_DEPTH_32F 单精度浮点数
IPL_DEPTH_64F 双精度浮点数

3. int channels:每个像素的通道数
可以为1,2,3或4

2.cvCreateImageHeader使用方法


2.1功能:创建图像首地址,并不会初始化空间内的数据

IplImage*cvCreateImageHeader( CvSize size, int depth, int channels );
参数说明:(同上)

3.查看cvCreateImage与cvCreateImageHeader源码==》区别


CV_IMPL IplImage *   cvCreateImage( CvSize size, int depth, int channels )
{
    IplImage *img = cvCreateImageHeader( size, depth, channels );
    assert( img );
    cvCreateData( img );
    return img;
}

// create IplImage header
CV_IMPL IplImage * cvCreateImageHeader( CvSize size, int depth, int channels )
{
IplImage *img = 0;

if( !CvIPL.createHeader )
{
    img = (IplImage *)cvAlloc( sizeof( *img ));
    cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,
                                CV_DEFAULT_IMAGE_ROW_ALIGN );
}
else
{
    const char *colorModel, *channelSeq;

    icvGetColorModel( channels, &colorModel, &channelSeq );

    img = CvIPL.createHeader( channels, 0, depth, (char*)colorModel, (char*)channelSeq,
                              IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL,
                              CV_DEFAULT_IMAGE_ROW_ALIGN,
                              size.width, size.height, 0, 0, 0, 0 );
}

    return img;
}

函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式
cvCreateImageHeader()与cvCreateData(),而cvCreateImageHeader()只是创建空间,并不会初始化空间内的数据。cvCreateImage 与cvCreateImageHeader均是IplImage* 类型的图像头指针,这两个函数的区别是cvCreateImage 除了分配图像头之外,还分配图像数据,而cvCreateImageHeader仅仅是分配图像头,并没有分配图像数据。

4.函数调用案例


#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
using namespace cv;
using namespace std;

static IplImage *img0 = NULL;
static IplImage *img1 = NULL;
static IplImage *img2 = NULL;
static IplImage *img3 = NULL;

int main(int argc, char** argv)
{
IplImage* gray;

uchar* dataGray;

int row;
int col;
int tempRow;
int tempCol;
int stepGray;

char filename[] = "148g.png";

gray = cvLoadImage(filename, CV_LOAD_IMAGE_UNCHANGED);

dataGray = (uchar*)gray->imageData;
stepGray = gray->widthStep / sizeof(uchar);

//test img0
//此方式可以在连续输入图像时,每张图像大小不确定时,且想在初始化时创建图像头
//先创建一个很小的图像空间头
img0 = cvCreateImageHeader(cvSize(1, 1), 8, 1); 
//初始化图像                      
cvInitImageHeader(img0,cvSize(gray->width,gray->height), 8, 1, 0, 4);
//连接数据
cvSetData(img0,gray->imageData, img0->widthStep);
//显示
cvNamedWindow("img0");
cvShowImage("img0", img0);
cvWaitKey(20);
//释放
cvReleaseImageHeader(&img0);  //将它的图像头释放,没有释放数据空间!
img0 = NULL;

// test img1
img1 = cvCreateImageHeader(cvSize(gray->width, gray->height), IPL_DEPTH_8U, 1);
cvSetData(img1,gray->imageData,img1->widthStep);

cvNamedWindow("img1");
cvShowImage("img1", img1);
cvWaitKey(20);

cvReleaseImageHeader(&img1);  //将它的图像头释放,没有释放数据空间!
img1 = NULL;

//test img2                   //此方法是已经确定传入图像的大小
img2 = cvCreateImage(cvSize(gray->width, gray->height), IPL_DEPTH_8U,1);
//赋值数据
memcpy(img2->imageData, gray->imageData, gray->widthStep*gray->height);

cvNamedWindow("img2");
cvShowImage("img2", img2);
cvWaitKey(20);

cvReleaseImage(&img2);   //将它的头和图像数据释放!
img2 = NULL;

//test img3
//先创建一个很小的图像空间头 因为不确定要传入图像的大小
img3 = cvCreateImageHeader(cvSize(1, 1), 8, 1); 
img3 = cvCreateImage(cvSize(gray->width, gray->height), IPL_DEPTH_8U, 1);
memcpy(img3->imageData, gray->imageData, gray->widthStep*gray->height);

cvNamedWindow("img3");
cvShowImage("img3", img3);
cvWaitKey(20);

cvReleaseImage(&img3);   //将它的头和图像数据释放!
img3 = NULL;


cvNamedWindow("gray");
cvShowImage("gray", gray);
cvWaitKey(20);

return 0;
}

以上4中方法都可以创建图像空间。

猜你喜欢

转载自blog.csdn.net/hanshanbuleng/article/details/81159402