CvArr,CvMat,IplImage这三者是继承的关系。

打开opencv 3.0的源码:

cvArr

/* CvArr* is used to pass arbitrary

 * array-like data structures

 * into functions where the particular

 * array type is recognized at runtime:

 */

typedef void CvArr;



oh god,它是可变类型的数据

cvMat

再看一下cvMat。

typedef struct CvMat
{
int type;
int step; /* for internal use only */
int* refcount;
int hdr_refcount; union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data; #ifdef __cplusplus
union
{
int rows;
int height;
}; union
{
int cols;
int width;
};
#else
int rows;
int cols;
#endif #ifdef __cplusplus
CvMat() {}
CvMat(const CvMat& m) { memcpy(this, &m, sizeof(CvMat));}
CvMat(const cv::Mat& m);
#endif }
CvMat;

这里先不管C++了,纯c的做法是:

typedef struct CvMat
{
int type;
int step; /* for internal use only */
int* refcount;
int hdr_refcount; union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data; int rows;
int cols; }
CvMat;

这里,cvMat有几个属性,到底是干什么的呢?

可以看看它的初始化函数:

CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL))
{
CvMat m; assert( (unsigned)CV_MAT_DEPTH(type) <= CV_64F );
type = CV_MAT_TYPE(type);
m.type = CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG | type;
m.cols = cols;
m.rows = rows;
m.step = m.cols*CV_ELEM_SIZE(type);
m.data.ptr = (uchar*)data;
m.refcount = NULL;
m.hdr_refcount = 0; return m;
}

看了之后恍然大悟:

type是矩阵中每一个数据点的类型。

cols是矩阵的列数。

rows当然是行数。

step是每一行的数据大小(应该是byte数吧)。

data是一个union的类型,里面是不同类型的指针,这样做的目的应该是可以接收 不同的数据类型吧。

比如你传了一个float*的指针进去,他就是float*了,反正这个联合体的大小就是sizeof(pointer) = 4了

internal use的先不管了。

在其他版本中把rows和height写在union里面的做法应该是做变量的兼容性吧。

IplImage

下面来重点看一下这个结构体:

typedef struct
#ifdef __cplusplus
CV_EXPORTS
#endif
_IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /* Ignored by OpenCV */
int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
char colorModel[4]; /* Ignored by OpenCV */
char channelSeq[4]; /* ditto */
int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels.
cvCreateImage can only create interleaved images */
int origin; /* 0 - top-left origin,
1 - bottom-left origin (Windows bitmaps style). */
int align; /* Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead. */
int width; /* Image width in pixels. */
int height; /* Image height in pixels. */
struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */
struct _IplImage *maskROI; /* Must be NULL. */
void *imageId; /* " " */
struct _IplTileInfo *tileInfo; /* " " */
int imageSize; /* Image data size in bytes
(==image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /* Pointer to aligned image data. */
int widthStep; /* Size of aligned image row in bytes. */
int BorderMode[4]; /* Ignored by OpenCV. */
int BorderConst[4]; /* Ditto. */
char *imageDataOrigin; /* Pointer to very origin of image data
(not necessarily aligned) -
needed for correct deallocation */ #ifdef __cplusplus
_IplImage() {}
_IplImage(const cv::Mat& m);
#endif
}
IplImage;

可以看出来,这个结构体和cvMat很像。

下面通过实际操作来understand一下这个结构体:

#include <cv.h>
#include <highgui.h> #define u8 unsigned char void image_operation(IplImage *image)
{
printf("nchannels:%d\n",image->nChannels);
printf("depth:%d\n",image->depth);
/* ./modules/core/include/opencv2/core/types_c.h:
* #define IPL_DATA_ORDER_PIXEL 0
*/
printf("dataOrder:%d\n",image->dataOrder);
printf("width:%d\n",image->width);
printf("height:%d\n",image->height);
printf("origin:%d\n",image->origin);
printf("widthStep:%d\n",image->widthStep); for (int y = 0; y<image->height ; y++) {
u8* row = (u8*)(image->imageData + y*image->widthStep);
for(int x = 0; x<image->width; x++) {
row[3*x + 1] = 0;
row[3*x + 2] = 0;
}
}
} int main(int argc,char **argv)
{ printf("this is image transforming plus\n");
IplImage *image;
image = cvLoadImage(argv[1]);
if(argc != 2)
{
std::cout << "No image data\n";
return -1;
} cvNamedWindow("image input");
cvNamedWindow("image output");
cvShowImage("image input", image);
image_operation(image);
cvShowImage("image output", image);
cvReleaseImage(&image);
cvWaitKey(0);
cvDestroyWindow("image input");
cvDestroyWindow("image output"); return 0;
}

这里读取一个图像,并且将两个通道变成0,结果如下:

tan@ubuntu:~/cv$ ./TransformImage image/1.jpg
this is image transforming plus
nchannels:3
depth:8
dataOrder:0
width:400
height:300
origin:0
widthStep:1200

从结果来看,这里把蓝色通道提取了,再次验证一下就可以发现opencv的存储是 BGR 顺序存储的。

重要的一个变量是image->widthStep,因为opencv会把图像数据4字节对齐,每过一行需要加上这个值而不是自己进行处理。

最新文章

  1. C语言 &#183; 查找整数 &#183; 基础练习
  2. C#小方法PadLeft 和 PadRight
  3. Android 数据库管理— — —创建数据库
  4. 数据库mysql优化方案
  5. Guava并发:ListenableFuture与RateLimiter示例
  6. Word中的字体大小
  7. Maven项目中的run as选项介绍
  8. 【练习】flashback基于scn的闪回查询
  9. JAVA 多态和异常处理作业——动手动脑以及课后实验性问题
  10. POJ 3368 Frequent values RMQ 训练指南 好题
  11. 树状数组HDU1166
  12. onethink对二维数组结果集进行排序
  13. iOS push全方位解析(二)【译文】&quot;——生成OpenSSL证书,Provisioning Profile
  14. qtpanel
  15. 安装wxWidgets
  16. SQL Server:SQL Like 通配符特殊用法:Escape 【转】
  17. VMware WorkStation安装时提示The MSI failed
  18. glmnetUtils: quality of life enhancements for elastic net regression with glmnet
  19. Exception in thread &quot;http-bio-8080-exec-2&quot; java.lang.OutOfMemoryError: PermGen space[解决方案]
  20. [转载] zookeeper 分布式锁服务

热门文章

  1. 记录ConcurrentHashMap的锁分离技术
  2. 给你的Mr.Right画张择偶地图像
  3. Spring AOP 深入剖析
  4. 安装node.js+express for win7的Web开发环境配置
  5. 关于SqlDateTime溢出的问题
  6. Spring学习笔记之 Spring IOC容器(二) 之注入参数值,自动组件扫描方式,控制Bean实例化方式,使用注解方式
  7. 利用Keydown事件阻止用户输入
  8. jquery获取复选框(checkbox)的选中值(一组和单个)
  9. Linux学习之四——磁盘与文件系统管理
  10. Linux学习之三——操作档案与目录