Opencv【7】---IplImage中四字节对其问题
2016-07-29 19:58
387 查看
问题概述
typedef struct _IplImage { int nSize; /* IplImage大小,=sizeof(IplImage)*/ int ID; /* 版本 (=0)*/ int nChannels; /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */ int alphaChannel; /* 被OpenCV忽略 */ int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */ char colorModel[4]; /* 被OpenCV忽略 */ char channelSeq[4]; /* 被OpenCV忽略 */ int dataOrder; /* 0 - 交叉存取颜色通道,对三通道RGB图像,像素存储顺序为BGR BGR BGR ... BGR; 1 - 分开的颜色通道,对三通道RGB图像,像素存储顺序为RRR...R GGG...G BBB...B。 cvCreateImage只能创建交叉存取图像 */ int origin; /* 0 - 顶—左结构, 1 - 底—左结构 (Windows bitmaps 风格) */ int align; /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */ int width; /* 图像宽像素数 */ int height; /* 图像高像素数*/ struct _IplROI *roi; /* 图像感兴趣区域. 当该值非空只对该区域进行处理 */ struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */ void *imageId; /* 同上*/ struct _IplTileInfo *tileInfo; /*同上*/ int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/ char *imageData; /* 指向排列的图像数据 */ int widthStep; /* 排列的图像行大小,以字节为单位 */ int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */ int BorderConst[4]; /* 同上 */ char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */ }IplImage;
可以知道IplImage数据结构体中有两个width,一是width属性;二是widthStep属性。前者是表示图像的每行像素数,后者指表示存储一行像素需要的字节数。在OpenCV里边,widthStep必须是4的倍数,从而实现字节对齐,有利于提高运算速度。
比如有一幅550x733像素的RGB图像(3通道),经过OpenCV中C接口的
cvLoadImage函数读取进来后,得到的
imageData不是550*733个像素,这时候产生了四字节对其问题,因为550*3=1650字节,对4取余是不为零的,则会补上两个字节到每行的后面。如果这个时候去用图像的
width、
height以及
imageData这三个信息去处理图像的话可能会出现意向不到的错误,比如你传入某个函数去处理这张图像数据,每次读取
width个字节,那么这个时候读完这个图像数据就会产生一个错位了,处理数据也就会出现问题了。
当然是用C++接口就没有这个问题了,通过Mat类来读取图像,没有四字节对其问题。
class CV_EXPORTS Mat { public: // ... a lot of methods ... ... /*! includes several bit-fields: - the magic signature - continuity flag - depth - number of channels */ int flags; //! the array dimensionality, >= 2 int dims; //! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions int rows, cols; //! pointer to the data uchar* data; //! pointer to the reference counter; // when array points to user-allocated data, the pointer is NULL int* refcount; // other members ... };
四字节问题处理
方式一:将IplImage数据结构转为Mat来操作Mat newImage(iplImage, true); // 设置为true基于原始图像拷贝一份数据
方式二:直接将原始数据提取出来
IplImage *image_color = cvLoadImage(argv[1], 1); if (!image_color) { fprintf(stderr, "cvLoadImage is failed\n"); return -1; } unsigned char * rowData = (unsigned char*)image_color->imageData; unsigned char *data = (unsigned char *)malloc(image_color->width * image_color->height * 3); for (int i = 0; i < image_color->height; i++){ memcpy(data + image_color->width * i *3, rowData + image_color->widthStep * i, image_color->width*3); } cvReleaseImage(&image_color);
相关文章推荐
- python中使用OpenCV进行人脸检测的例子
- opencv 做人脸识别 opencv 人脸匹配分析
- 使用opencv拉伸图像扩大分辨率示例
- Android Studio中配置OpenCV库开发环境的教程
- 基于C++实现kinect+opencv 获取深度及彩色数据
- visual studio 2012安装配置方法图文教程 附opencv配置教程
- OpenCV 2.4.3 C++ 平滑处理分析
- Python中使用OpenCV库来进行简单的气象学遥感影像计算
- 利用Python和OpenCV库将URL转换为OpenCV格式的方法
- python结合opencv实现人脸检测与跟踪
- Python环境搭建之OpenCV的步骤方法
- Python+Opencv识别两张相似图片
- Python实现OpenCV的安装与使用示例
- 在树莓派2或树莓派B+上安装Python和OpenCV的教程
- opencv-python学习一--人脸检测
- 在Ubuntu上安装OpenCV3.0和Python-openCV的经历
- 使用 Java 开发 OpenCV 应用
- OpenCV配置,从来没有这么简单!
- ubuntu下opencv和qt的安装配置
- Java程序内存分析:使用mat工具分析内存占用