OpenCV里IplImage的widthStep参数 和width参数
一直以为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参数相关推荐
- 【转】OpenCV里IplImage数据结构极易出错的问题,IplImage和单字节char*的相互转换
http://blog.csdn.net/liuyi1985/article/details/2174328 http://blog.csdn.net/liuyi1985/article/detail ...
- OpenCV里IplImage数据结构中的width和widthStep
转自http://nst1987.blog.163.com/blog/static/14950891120101120114029646/ IplImage有两个属性容易导致错误:width和widt ...
- 关于OpenCV中IplImage的字节对齐问题
最近利用做项目,遇到了一个问题:我是用opencv读的图像,然后自己新开辟了一个空间,以下是代码 Byte *inputImage=NULL; IplImage* image_get=NULL; im ...
- 【OpenCV】IplImage和char *的相互转换,以及极易忽视的细节
OpenCV中IplImage和单字节char*的相互转换 从 IplImage到 char* : data = image->imageData //对齐的图像数据或者data = image ...
- OpenCV中IplImage和单字节char*的相互转换
已知 IplImage* image 和 char* data 从 IplImage 到 char* : data = image->imageData //对齐的图像数据 或者 data = ...
- OpenCV中IplImage/CvMat/Mat转化关系
原文链接:http://www.cnblogs.com/summerRQ/articles/2406109.html 如对内容和版权有何疑问,请拜访原作者或者通知本人. opencv中常见的与图像操作 ...
- Opencv中IplImage的四字节对齐问题
一.结构解释 IplImage数据结构体中有两个宽度: 1 是width属性,表示图像的每行像素数: 2 是widthStep属性,表示存储一行像素需要的字节数. 在OpenCV里边,widthSte ...
- OpenCV中 IplImage 与 Mat的区别
IplImage: 在OpenCV中IplImage是表示一个图像的结构体,也是从OpenCV1.0到目前最为重要的一个结构: 在之前的图像表示用IplImage,而且之前的OpenCV是用C语言编写 ...
- OpenCV中IplImage与Qt中的QImage转化
OpenCV中IplImage与Qt中的QImage转化 在工程中由于要涉及到OpenCV中IplImage与Qt中的QImage转化,所以写了两个类: #ifndef IMAGETRANSFORM_ ...
最新文章
- J360-cloud SpringCloud系列二:服务发现Discovery Service
- xampp mysql 端口被占用_xampp安装后apache 80端口被占用的解决方法
- Linux 下 zip unzip压缩与解压
- jQuery中deferred对象的使用(二)
- therefore/so/hence/then/accordingly/Thus
- linux es连接mysql_Linux下ES,kibana,mysql,kafka,zookeeper启动关闭方式
- 女性心理学:全球女性学霸时代来临
- 中文版边缘计算白皮书发布,引领行业新趋势
- envi5.6处理gf3(SAR)详细过程记录
- 嵌入式系统开发-麦子学院(12)——ARM Bootloader开发
- Java程序员该如何准备明年的「金三银四」跳槽季,你准备好了吗?
- 社区发现算法——(Spectral Clustering)谱聚类算法
- 计算机一级和二级考试内容有什么不同吗?
- 操作系统安全防护技术
- STM32L0系列之ADC采集
- 【本地调试环境一键安装包】php+mysql平台搭建集成软件总汇【php环境汇总】
- CB Insights:7个颠覆式创新框架
- 前端代码调试:Webstorm调试js
- 操作ocx控件和注册反注册ocx
- CreateProcess 函数