一直以为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                    3                             12

3                    1                             4

5                    3                            16

5                    1                             8

7                    3                             24

7                    1                             8

4                    3                             12

4                    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的倍数?

OpenCV里IplImage的widthStep参数 和width参数相关推荐

  1. 【转】OpenCV里IplImage数据结构极易出错的问题,IplImage和单字节char*的相互转换

    http://blog.csdn.net/liuyi1985/article/details/2174328 http://blog.csdn.net/liuyi1985/article/detail ...

  2. OpenCV里IplImage数据结构中的width和widthStep

    转自http://nst1987.blog.163.com/blog/static/14950891120101120114029646/ IplImage有两个属性容易导致错误:width和widt ...

  3. 关于OpenCV中IplImage的字节对齐问题

    最近利用做项目,遇到了一个问题:我是用opencv读的图像,然后自己新开辟了一个空间,以下是代码 Byte *inputImage=NULL; IplImage* image_get=NULL; im ...

  4. 【OpenCV】IplImage和char *的相互转换,以及极易忽视的细节

    OpenCV中IplImage和单字节char*的相互转换 从 IplImage到 char* : data = image->imageData //对齐的图像数据或者data = image ...

  5. OpenCV中IplImage和单字节char*的相互转换

    已知 IplImage* image 和 char* data 从 IplImage 到 char* : data = image->imageData //对齐的图像数据 或者 data =  ...

  6. OpenCV中IplImage/CvMat/Mat转化关系

    原文链接:http://www.cnblogs.com/summerRQ/articles/2406109.html 如对内容和版权有何疑问,请拜访原作者或者通知本人. opencv中常见的与图像操作 ...

  7. Opencv中IplImage的四字节对齐问题

    一.结构解释 IplImage数据结构体中有两个宽度: 1 是width属性,表示图像的每行像素数: 2 是widthStep属性,表示存储一行像素需要的字节数. 在OpenCV里边,widthSte ...

  8. OpenCV中 IplImage 与 Mat的区别

    IplImage: 在OpenCV中IplImage是表示一个图像的结构体,也是从OpenCV1.0到目前最为重要的一个结构: 在之前的图像表示用IplImage,而且之前的OpenCV是用C语言编写 ...

  9. OpenCV中IplImage与Qt中的QImage转化

    OpenCV中IplImage与Qt中的QImage转化 在工程中由于要涉及到OpenCV中IplImage与Qt中的QImage转化,所以写了两个类: #ifndef IMAGETRANSFORM_ ...

最新文章

  1. J360-cloud SpringCloud系列二:服务发现Discovery Service
  2. xampp mysql 端口被占用_xampp安装后apache 80端口被占用的解决方法
  3. Linux 下 zip unzip压缩与解压
  4. jQuery中deferred对象的使用(二)
  5. therefore/so/hence/then/accordingly/Thus
  6. linux es连接mysql_Linux下ES,kibana,mysql,kafka,zookeeper启动关闭方式
  7. 女性心理学:全球女性学霸时代来临
  8. 中文版边缘计算白皮书发布,引领行业新趋势
  9. envi5.6处理gf3(SAR)详细过程记录
  10. 嵌入式系统开发-麦子学院(12)——ARM Bootloader开发
  11. Java程序员该如何准备明年的「金三银四」跳槽季,你准备好了吗?
  12. 社区发现算法——(Spectral Clustering)谱聚类算法
  13. 计算机一级和二级考试内容有什么不同吗?
  14. 操作系统安全防护技术
  15. STM32L0系列之ADC采集
  16. 【本地调试环境一键安装包】php+mysql平台搭建集成软件总汇【php环境汇总】
  17. CB Insights:7个颠覆式创新框架
  18. 前端代码调试:Webstorm调试js
  19. 操作ocx控件和注册反注册ocx
  20. CreateProcess 函数

热门文章

  1. 判断浏览器是否为IE内核的最简单的方法
  2. kylinH5框架之项目脚手架
  3. 最新的vue webpack模板没有dev-server.js文件,进行后台数据模拟笔记
  4. VUE 数据绑定模块渲染 computed(实现通过路由id 查询数据json结构,对应的值来放在面包屑中)...
  5. 数字签名与HTTPS详解
  6. Axure实现多用户注册验证
  7. DNN模型训练词向量原理
  8. 汇编的艺术(01)sizeof operator
  9. Visual studio 打包
  10. 从今开始,好好学习一下算法!