IplImage中的widthStep大小计算及原理
来源:互联网 发布:一个程序员的奋斗史41 编辑:程序博客网 时间:2024/05/17 03:46
一直以为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
根据(1)式,已知IPL_DEPTH_SIGN、align、depth 的大小,分别手动计算如下图像的widthStep:
图像宽度
3
3
5
5
7
7
4
4
为了进一步验证手算的正确性,我们编程实现输出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 =
可见widthStep直接影响到imageData的数据长度。在操作imageData时,我们要避开对OpenCV自动补齐的内存进行操作,如直方图计算等。
写到这里,可能有人会问,我们平常都用widthStep = width * nChannels,怎么就没出错?我之前也一直在疑惑,合理的解释是,一般在实际应用中,图像的宽度一般为128, 256, 240, 320, 356,704等,刚好这些数字都能被4整除,widthStep刚好等于width * nChannels, 所以OpenCV并没有为这些图像分配多的内存,因此我们在对imageData做顺序操作也没出错。但是,请问谁能保证图像的宽度一定会是4的倍数?
- IplImage中的widthStep大小计算及原理
- IplImage中的widthStep大小计算及原理
- IplImage中的widthStep大小计算及原理
- 关于IplImage中widthstep的大小与width,nchanne
- OpenCV里IplImage数据结构中的width和widthStep
- 关于IplImage中widthstep的大小与width,nchannels等的关系的问题
- 关于IplImage中widthstep的大小与width,nchannels等的关系的问题_widthstep
- IPlImage的width和widthStep
- OpenCV里IplImage的widthStep参数
- widthstep
- OpenCV中的width和widthstep
- OpenCV 中结构体IplImage 成员width widthStep使用注意事项
- OpenCV里IplImage的widthStep参数 和width参数
- OpenCV里IplImage的widthStep参数 和width参数
- iphone 屏幕大小及计算
- 结构体大小的计算及设置内存字节对齐数原理理解
- Cocos2D中的纹理大小计算
- JPG图像大小计算原理解释
- CCBPM节点访问规则与绑定人员的关联
- 随机产生字符串
- Java-泛型-01
- adb详细介绍以及常用adb命令
- iOS App Archive & Generic Xcode Archive
- IplImage中的widthStep大小计算及原理
- 树莓派警署无线AP
- HttpClient和HtmlParser配合实现自动CAS单点登录系统抽取页面信息
- Sqlite数据库中"未处理SQLiteException"问题
- Linux内核的抽象结构
- ubuntu下终端操作MySql数据库的命令
- String与StringBuffer的区别
- android中drawable资源的解释及例子
- 百度地图系列02——地图移动到指定点