admin 管理员组

文章数量: 1086019


2024年4月16日发(作者:garage的英语发音)

 IplImage的像素的访问

当处理图象数据时,通常需要快速高效。使用如cvSet*D或和它等效的函数会造成调

用时的开销。我们应该尽可能使用直接存取图象内部数据的方法。有了IplImage内部结

构的知识,我们现在可以理解最好的方法。

尽管通常OpenCV提供很多对图象的操作优化良好的例程,但是经常会有些任务是库

里找不到包装好的例程的。下面我们考虑一个例子,我们想要把三通道HSV图象的饱合度

调整为255(8位图象的最大值)而保持色调不变。要完成这个任务最好是我们自己处理

图象的每个象素。这和我们前边对矩阵的操作相似,但在IplImage和CvMat之间也有一

些主要的不同。例3-11演示了高效的方式。

例3-11,把HSV图象的S、V分量最大化:

void saturate_sv( IplImage* img ) {

for( int y=0; yheight; y++ ) {

uchar* ptr = (uchar*) (img->imageData + y * img->widthStep);

for( int x=0; xwidth; x++ ) {

ptr[3*x+1] = 255;

ptr[3*x+2] = 255;

}

}

}

我们只是简单的直接计算相关行y最左边的象素的指针ptr(We simply compute the

pointer ptr directly as the head of the relevant row y)。从那里为参考,我们引用第x

列的饱合度数值。因为图象是三通道的,第c通道的地址为3*x+c。

在OpenCV中,一副HSV图象和RGB图象,除了对通道的翻译有所不同,其它是没

有区别的。因此由一副HSV图象构建一副RGB图象实际所有的操作完全只在“数据”区

域。在图象头中,没有任何成员用来表明数据通道的意义。

IplImage和CvMat相比一个重要的不同是imageData的行为。CvMat的数据元素

是一个联合体,所以必须说明你想要的指针类型;imageData是一个byte型(uchar*)。

我们已经知道被指向的数据不一定是uchar类型,这意味着当对指针作算术运算时,你可

以简单的加上widthSetp(同样是以字节数为度量的)而不用担心实际的数据类型,直需

在做完加法后,把你计算所得的指针转换成你想要的数据类型。总结:当对矩阵操作时,

你必须对偏移量进行缩减,因为数据指针可能不是byte型;而当对图象操作时,你可以使

用“看上去”那么多的偏移量,因为数据指针永远是byte型,因此在你准备使用它时,只

需把整部分做类型转换。

访问图象数据的补充资料


本文标签: 图象 数据 指针 操作