数据结构操作与运算-IplImage数据结构操作(1)

前面的IplImage数据结构介绍的部分,是用直接存取的方式对IplImage数据结构直接提取它的值,而实际上,OpenCV的程序人员希望能刻意的将IplImage包起来,用子程序间接存取的方式去给使用者操作,由于OpenCV是以C语言为基础的,因此它无法做到面向对象封装的操作,因此数据 结构内的数值是可以任意检视的,不会有public及private的影响,而OpenCV提供了以下对IplImage操作的函数.

IplImage数据结构的操作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>


int Dims;
int Height;
int Width;
int COIChannel;

int main()
{
    IplImage *Image1;
    CvRect Rect1,Rect2;

    uchar *ptr1;
    CvSize Size1;
    CvScalar Scalar1;

    Image1=cvLoadImage("bower.jpg",1);

    Dims=cvGetDims(Image1,0);
    Height=cvGetDimSize(Image1,0);
    Width=cvGetDimSize(Image1,1);

    Rect1=cvRect(140,305,115,165);
    cvSetImageCOI(Image1,1);
    cvSetImageROI(Image1,Rect1);

    COIChannel=cvGetImageCOI(Image1);
    Rect2=cvGetImageROI(Image1);
    Size1=cvGetSize(Image1);

    ptr1=cvPtr2D(Image1,50,40);

    Scalar1=cvGet2D(Image1,50,40);

    printf("pic ROI Information==\n");
    printf("Dims is : %d\n",Dims);
    printf("Height is : %d\n",Height);
    printf("Width is : %d\n",Width);
    printf("Set COI is : %d\n",COIChannel);
    printf("ROI Size is : (%d,%d)\n\n",Size1.height,Size1.width);

    printf("The Pointer 2D (50,40)Channels is : %d %d %d\n",*ptr1,*(ptr1+1),*(ptr1+2));
    printf("The Scalar 2D (50,40) Channels is : %.1f %.1f %.1f\n",Scalar1.val[0],Scalar1.val[1],Scalar1.val[2]);

    cvSet2D(Image1,50,40,cvScalar(255,255,255));
    printf("The Pointer 2D (50,40)Channels is : %d %d %d\n",*ptr1,*(ptr1+1),*(ptr1+2));

    cvNamedWindow("Bower ROI",1);

    cvShowImage("Bower ROI",Image1);
    cvResetImageROI(Image1);
    cvNamedWindow("Bower",1);
    cvShowImage("Bower",Image1);
    cvWaitKey(0);

}

原始图片:


执行结果:


一 开始,打开图像文件配置给ROI的CvRect数据结构大小空间,用cvSetImageCOI()配置感兴趣的颜色(Color Of Interesting)配置为信道一,蓝色,用cvSetImageROI()选定感兴趣的区域而相对的,cvGetImageCOI()跟 cvSetImageROI()则是取得信息,cvGetDims()为取得维度,因为是图片,所以当然是二维,再来是取得宽跟高,它也可以使用 cvGetSize()取得CvSize数据结构的宽跟高信息,cvPtr2D()是用指针的方式取得图片坐标位置,并且数据为信道一,藉由指标运算+1 的方式如*(ptr1+1),可以取得信道二,信道三...由于取得的是指标位置,所以可以直接对它做直接修改数值,而cvGet2D()是传值呼叫,必 须要对它做cvSet()2D才能完成存取的动作,这是面向对象里很基本Get跟Set的概念,而后面就直接用指标*ptr1得方式直接printf() 修改的值出来,最后的部分cvResetImageROI()将ROI重置,因此就还原成原来的图片了,值得注意的是,这边修改了其中的一个点,而重置 后,被修改的点的部分仍然不会恢复原状,ROI只是对图像做平移及缩小检视范围罢了.另一个比较重要的部分cvPtr2D()输出为uchar *类型,cvGet2D()为CvScalar数据结构,在存取的时候千万不能搞错了,尤其是cvPtr2D()这个函数.

在 OpenCV对IplImage数据结构的操作是很随意的,很多函数甚至可以直接跟CvMat数据结构共享,但实际上,这是危险的,OpenCV的开发没 有做到降低程序设计的耦合性,也因为IplImage跟CvMat所使用的子程序及变量是有冲突,对于那些共享的子程序的回传值套用在两个不同的数据结构 上,对使用者来讲会有凌乱的困扰,但是它仍是有优点,它会比一些被封装整理过的程序快一些,这仍会是个事实.

cvSetImageCOI()
配置感兴趣的颜色(Color Of Interesting),第一个参数为IplImage数据结构,第二个参数为信道数据,如果为0表示不设立
cvSetImageCOI(IplImage数据结构,信道数据)

cvSetImageROI()
配置感兴趣的区域(Region Of Interesting),第一个参数为IplImage数据结构,第二个参数为CvRect选取的区域大小.
cvSetImageROI(IplImage数据结构,RvRect区块数据结构)

cvGetImageCOI()
取得图像配置COI数据.
cvGetImageCOI(IplImage数据结构)

cvGetImageROI()
取得图像ROI数据
cvGetImageROI(IplImage数据结构)

cvResetImageROI()
重置图像ROI,也就是将CvRect所选定的区域取消掉,但是CvRect区域内修改的值不会被复原.
cvResetImageROI(IplImage数据结构)

cvGetDims()
取得维度信息,这边可以跟IplImage,CvMat共享,当然,图片一定是二维数组
cvGetDims(IplImage数据结构或CvMat数据结构)

cvGetDimSize()
取得IplImage图像或CvMat矩阵的空间大小数据0为高(height)/行(row),数据1为宽(width)/列(colunm)
cvGetDimSize(IplImage数据结构或CvMat数据结构,空间大小代号)

cvGetSize()
取得IplImage图像或CvMat矩阵的空间大小,回传值是CvSize数据结构.
cvGetSize(IplImage数据结构或CvMat数据结构)

cvPtr2D()
取得二维空间的坐标值,此为一整串的函数之一,包括有

cvPtr1D()
cvPtr2D()
cvPtr3D()
cvPtrND()

3D跟ND则不能用IplImage及CvMat实例,这系列函数回传值都是uchar *类型的內存位址,利用指标+1,+2,+3可以选择其他信道
cvPtr2D(IplImage数据结构或CvMat数据结构,X轴坐标数据,Y轴坐标数据)

cvPtr1D()
取得一维空间的坐标值,回传值为uchar *內存位址,也可以用来取得二维数组坐标值(因为IplImage,CvMat数据结构都是由一维数组组合而成的),但是不建议用一维函数去实例二,三维空间只是增加程序设计的难度及降低可读性
cvPtr1D(IplImage数据结构或CvMat数据结构,一维数组Index数据)

cvGet2D()
取得二维空间的标量值(CvScalar),亦为一整串的函数之一,其中包括有

cvGet1D()
cvGet2D()
cvGet3D()
cvGetND()

3D及ND不支持IplImage数据结构及CvMat,回传值皆为CvScalar数据结构,对应cvSet*D()系列函数.
cvGet2D(IplImage数据结构或CvMat数据结构,X轴坐标数据,Y轴坐标数据)

cvGet1D()
取得IplImage数据结构及CvMat数据结构一维空间的标量值(CvScalar),可以用来取得二维数组坐标值,但不建议二维数组用cvGet1D()实例.
cvGet1D(IplImage数据结构或CvMat数据结构,一维数组Index数据)

cvSet2D()
为cvGet*D()系列的对应,也为一整串函数之一,其中包括

cvSet1D()
cvSet2D()
cvSet3D()
cvSetND()

为配置IplImage,CvMat标量数据之用途.
cvSet2D(IplImage数据结构或CvMat数据结构,X轴坐标数据,Y轴坐标数据,CvScalar数据结构)

cvSet1D()
配置IplImage数据结构及CvMat数据结构一维空间的标量值(CvScalar),可以用来取得二维数组坐标值,但不建议二维数组用cvSet1D()实例.
cvSet1D(IplImage数据结构或CvMat数据结构,一维数组Index数据,CvScalar数据结构)