OpenCV入门(四)基本数据类型

IplImage数据结构

IplImage
  |-- int  nChannels;     // 颜色通道数目 (1,2,3,4)
  |-- int  depth;         // 像素的位深: 
  |                       //   IPL_DEPTH_8U, IPL_DEPTH_8S, 
  |                       //   IPL_DEPTH_16U,IPL_DEPTH_16S, 
  |                       //   IPL_DEPTH_32S,IPL_DEPTH_32F, 
  |                       //   IPL_DEPTH_64F
  |-- int  width;         // 图像宽度(像素为单位)
  |-- int  height;        // 图像高度
  |-- char* imageData;    // 图像数据指针
  |                       // 注意彩色图像按BGR顺序存储数据
  |-- int  dataOrder;     // 0 - 将像素点不同通道的值交错排在一起,形成单一像素平面 
  |                       // 1 - 把所有像素同通道值排在一起,形成若干个通道平面,再把平面排列起来
  |                       // cvCreateImage 只能创建像素交错排列式的图像
  |-- int  origin;        // 0 – 像素原点为左上角,
  |                       // 1 – 像素原点为左下角 (Windows bitmaps style)
  |-- int  widthStep;     // 相邻行的同列点之间的字节数    width * nChannels * depth / 8
  |-- int  imageSize;     // 图像的大小(字节为单位) = height*widthStep
  |-- struct _IplROI *roi;// 图像的感兴趣区域(ROI). ROI非空时对图像的
  |                       // 处理仅限于ROI区域.
  |-- char *imageDataOrigin; // 图像数据未对齐时的数据原点指针
  |                          // (需要正确地重新分配图像内存 )
  |                          // (needed for correct image deallocation)
  |-- int  align;         // 图像数据的行对齐: 4 or 8 byte alignment
  |                       // OpenCV 中无此项,采用widthStep代替
  |-- char colorModel[4]; // 颜色模型 – OpenCV中忽略此项
点击打开链接 http://wiki.opencv.org.cn/index.php/Cxcore%E5%9F%BA%E7%A1%80%E7%BB%93%E6%9E%84#IplImage

IplImage 是CvMat的子类,CvMat是OpenCV的矩阵结构,其定义为,

CvMat

多通道矩阵

typedef struct CvMat
 {
  int type; /* CvMat 标识 (CV_MAT_MAGIC_VAL), 元素类型和标记 */
  int step; /* 以字节为单位的行数据长度*/
  int* refcount; /* 数据引用计数 */
  union
   {
    uchar* ptr;
    short* s;
    int* i;
    float* fl;
    double* db;
   } data; /* data 指针 */
  #ifdef __cplusplus
  union
   {
     int rows;
     int height;
   };
  union
   {
     int cols;
     int width;
   };
  #else
   int rows; /* 行数 */
   int cols; /* 列数*/
  #endif
 } CvMat;

IplImage从本质上将是一个CvMat对象,但是它还有一些成员变量将矩阵解释为图像。


ROI 是IplImage结构体重的重要参数,用于对图像中的一部分进行操作,其中
cvSetImageROI()用于设置ROI区域 cvResetImageROI()用于取消ROI
其函数形式为:

void cvSetImageROI( IplImage* image, CvRect rect );
void cvResetImageROI( IplImage* image );

利用ROI处理lena感兴趣的区域

1.  用imageROI改变某范围的像素


调用函数: doROIdemo(img,150,150,300,300,150);
/*
对图像中感兴趣的部分的处理
*/

#include "highgui.h"
#include "cv.h"

void doROIdemo(IplImage* img, int x, int y, int width, int height,int add)
{
	cvSetImageROI(img, cvRect(x,y,width,height));
	cvAddS(img,cvScalar(add),img);
	cvNamedWindow("roi_add",1);
	cvShowImage("roi_add",img);
	cvWaitKey(0);
}

结果:



2.  用widthStep实现

有些时候在处理的过程中,想在操作过程中设置和保持一幅图像的多个子区域处于活动状态,但是ROI只能串行处理并且必须不断设置和重置。
用widthStep处理的具体方法如下:
1.创建一个图像头,让其width和height的值等于interest_rect的width和height的值。
2.按interest_img的起点设置图像起点(左上角或者左下角)。
3.设置子图像的widthStep与较大的interest_img相同。
4.这样即可在子图像中逐行地步进到大图像里子区域中下一行开始处的合适位置。
5.最后设置子图像的imageData指针指向兴趣子区域的开始。

void doROIdemo(IplImage* img, int x, int y, int width, int height,int add)
{
	CvRect interest_rect = cvRect(x,y,width,height);
	IplImage* sub_img = cvCreateImageHeader(
		cvSize(
		interest_rect.width,
		interest_rect.height
		),
		img->depth,
		img->nChannels
		);
	sub_img->origin = img->origin;
	sub_img->widthStep = img->widthStep;
	sub_img->imageData = img->imageData 
		+ interest_rect.x * img->widthStep 
		+ interest_rect.y * img->nChannels;
	cvAddS(sub_img,cvScalar(150),sub_img);

	cvNamedWindow("roi_add",1);
	cvShowImage("roi_add",sub_img);
	cvWaitKey(0);
	cvReleaseImageHeader(&sub_img);
}

结果:



在上面的函数中,用到了cvRect等结构体,对这些结构体说明:

CvRect

矩形框的偏移和大小

typedef struct CvRect
 {
  int x; /* 方形的最左角的x-坐标  */
  int y; /* 方形的最上或者最下角的y-坐标 */
  int width; /* 宽 */
  int height; /* 高 */
 }
 CvRect;
/* 构造函数*/
inline CvRect cvRect( int x, int y, int width, int height );
{ 
      CvRect os;
      
      os.x = x;
      os.y = y;
      os.width = width;
      os.height = heigth;
      
      reture os;
}

CvSize

矩形框大小,以像素为精度

typedef struct CvSize
 {
  int width;  /* 矩形宽 */
  int height; /* 矩形高 */
 }
 CvSize;
/* 构造函数 */
inline CvSize cvSize( int width, int height );

注意:构造函数的cv是小写!


CvScalar

可存放在1-,2-,3-,4-TUPLE类型的捆绑数据的容器

typedef struct CvScalar
 {
  double val[4]
 }
 CvScalar;
/* 构造函数:用val0初始化val[0]用val1初始化val[1], 以此类推*/
inline CvScalar cvScalar( double val0, double val1,
                           double val2, double val3);

{  CvScalar  arr;
    
    arr.val[4] = {val0,val1,val2,val3};
  
    reture arr;}
/* 构造函数:用val0123初始化所有val[0]...val[3] */
inline CvScalar cvScalarAll( double val0123 );
 
  { CvScalar arr;
 
     arr.val[4] = {val0123,val0123,val0123,val0123,};

     reture arr;}
/* 构造函数:用val0初始化val[0],用0初始化val[1],val[2],val[3] */
inline CvScalar cvRealScalar( double val0 );

    { CvScalar arr;
       
       arr.val[4] = {val0};
   
       reture arr;}


CvPoint

二维坐标系下的点,类型为整型

typedef struct CvPoint
 {
  int x; /* X坐标, 通常以0为基点 */
  int y; /* y坐标, 通常以0为基点 */
 }
CvPoint;
/* 构造函数 */
inline CvPoint cvPoint( int x, int y );
/* 从 CvPoint2D32f类型转换得来 */
inline CvPoint cvPointFrom32f( CvPoint2D32f point )

http://wiki.opencv.org.cn/index.php/Cxcore%E5%9F%BA%E7%A1%80%E7%BB%93%E6%9E%84#IplImage
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值