OpenCV里IplImage的widthStep参数 和width参数

OpenCV里IplImage的widthStep参数 和width参数前者是表示图像的每行像素数,后者指表示存储一行像素需要的字节数。在OpenCV里边,widthStep必须是4的倍数,从而实现字节对齐,有利于提高运算速度。如果8U单通道图像宽度为3,那么widthStep是4,加一个字节补齐。这个图像的一行需要4个字节,只使用前3个,最后一个空着。也就是一个宽3高3的图像的imageData数据大小为4*3=12字节。

大家好,又见面了,我是你们的朋友全栈君。

      一直以为IplImage结构体中的widthStep元素大小等于width*nChannels,大错特错!(为了快速访问,要内存对齐啊)查看OpenCV2.1的源码,在src/cxcore/cxarray.cpp文件中,找到cvInitImageHeader函数,函数中对widthStep大小赋值如下:

  image->widthStep = (((image->width * image->nChannels *(image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));                                           

     其中IPL_DEPTH_SIGN的定义可以在cxtypes.h中找到,定义为:#define IPL_DEPTH_SIGN 0x80000000, align的大小为CV_DEFAULT_IMAGE_ROW_ALIGN,其大小在cxmisc.h中定义为:#define  CV_DEFAULT_IMAGE_ROW_ALIGN 4,depth取8位深度。

     根据(1)式,已知IPL_DEPTH_SIGN、align、depth 的大小,分别手动计算如下图像的widthStep:

        图像宽度     图像通道数              计算得到的widthStep

                           3                             12

                           1                             4

                           3                            16

                           1                             8

                           3                             24

                           1                             8

                           3                             12

                           1                             4

        为了进一步验证手算的正确性,我们编程实现输出widthStep的大小,程序如下:


IplImage *image_33 = cvCreateImage(cvSize(3, 3), 8, 3);
          IplImage *image_31 = cvCreateImage(cvSize(3, 3), 8, 1);
          IplImage *image_53 = cvCreateImage(cvSize(5, 3), 8, 3);
          IplImage *image_51= cvCreateImage(cvSize(5, 3), 8, 1);
          IplImage *image_73 = cvCreateImage(cvSize(7, 3), 8, 3);
          IplImage *image_71 = cvCreateImage(cvSize(7, 3), 8, 1);

          printf("%d, %d, %d, %d, %d, %d", image_33->widthStep,image_31->widthStep,
     image_53->widthStep,image_51->widthStep,image_73->widthStep,image_71->widthStep);

           运行结果为:12, 4, 16, 8, 24, 8, 与手动计算结果相同。

          从网上查阅资料,OpenCV分配的内存按4字节对齐,这样我们对上述计算的结果可以有个合理的解释,如宽度为3、通道数为3的图像,每一行需要的 实际内存长度为3*3,为了内存对齐,OpenCV会在每行末尾自动补上3个字节的内存,内存初始化都为0,所以widthStep变为了12。

widthStep大小对IplImage极为重要,在cxarray.cpp中,我们可以找到如下代码行:

image->imageSize = image->widthStep * image->height;

img->imageData = img->imageDataOrigin =(char*)cvAlloc( (size_t)img->imageSize );

      可见widthStep直接影响到imageData的数据长度。在操作imageData时,我们要避开对OpenCV自动补齐的内存进行操作,如直方图计算等。

写到这里,可能有人会问,我们平常都用widthStep = width * nChannels,怎么就没出错?我之前也一直在疑惑,合理的解释是,一般在实际应用中,图像的宽度一般为128, 256, 240, 320, 356,704等,刚好这些数字都能被4整除,widthStep刚好等于width * nChannels, 所以OpenCV并没有为这些图像分配多的内存,因此我们在对imageData做顺序操作也没出错。但是,请问谁能保证图像的宽度一定会是4的倍数? 


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141997.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • .h5文件的读取_python读写h5文件

    .h5文件的读取_python读写h5文件**关于hdf5文件**HDF(HierarchicalDataFormat)指一种为存储和处理大容量科学数据设计的文件格式及相应库文件。详见其官方介绍:https://support.hdfgroup.org/HDF5/。Python中有一系列的工具可以操作和使用HDF5数据,这里只介绍h5py。一个HDF5文件是存储两类对象的容器,这两类对象分别为:dataset…

    2025年10月15日
    2
  • Python实现排序算法之快速排序

    Python实现快速排序原理首先选取任意一个数据(通常选取数组的第一个数)作为关键数据,然后将所有比它小的放到它前面,所有比它大的放到它后面,这个过程称为一趟快速排序快速排序原理图如下:实现

    2021年12月18日
    57
  • 什么是ER图?数据库ER图基础概念整理

    什么是ER图?数据库ER图基础概念整理前置知识概述:数据模型的基本概念模型就是对现实世界特征的模拟和抽象,数据模型是对现实世界数据特征的抽象。对于具体的模型人们并不陌生,如航模飞机、地图和建筑设计沙盘等都是具体的模型。最常用的数据模型分为概念数据模型和基本数据模型。1)概念数据模型概念数据模型也称为信息模型,是按用户的观点对数据和信息建模,是现实世界到信息世界的第一层抽象,强调其语义表达功能,易于用户理解,是用户和数据库设计人员交流的语言,主要用于数据库设计。这类模型中最著名的是实体联系模型,简称E-R模型。2)基本数据

    2022年6月21日
    43
  • VCL组件之编辑控件「建议收藏」

    VCL组件之编辑控件「建议收藏」Note以后将用两种方式提及组件,以组件的名称或定义组件的VCL类的名称。可以说“Label组件用于……”或说“TLabel用于……”,这两种方式谈到的是同一组件。编辑控件(EditContro

    2022年7月3日
    38
  • siamFC_memorytest代码

    siamFC_memorytest代码文章目录1、architecture2、training3、test本文对SiamFC代码进行详细分析,并从代码角度阐述理论。

    2022年10月1日
    2
  • idea2021.8激活码-激活码分享

    (idea2021.8激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlKU…

    2022年3月22日
    52

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号