CvMemStorage、ConvertScale,cvConvert , cvScale 、UpdateMotionHistory

1、CvMemStorage *storage=cvCreateMemStorage(block_size);
用来创建一个内存存储器,来统一管理各种动态对象的内存。
函数返回一个新创建的内存存储器指针。
参数block_size对应内存器中每个内存块的大小,为0时内存块默认大小为64k。
 
2、CvSeq* cvCreateSeq(int seq_flags,int header_size,int elem_size,CvMemStorage* storage)
功能: 创建一序列
说明:CvSeq本身就是一个可增长的序列,不是固定的序列
参数
seq_flags为序列的符号标志。如果序列不会被传递给任何使用特定序列的函数,那么将它设为0,否则从预定义的序列类型中选择一合适的类型。 Header_size为序列头部的大小;必须大于或等于sizeof(CvSeq)。如果制定了类型或它的扩展名,则此类型必须适合基类的头部大小。 Elem_size为元素的大小,以 字节计。这个大小必须与序列类型(由seq_flags指定)相一致。例如,对于一个点的序列,元素类型 CV_SEQ_ELTYPE_POINT应当被指定,参数elem_size必须等同于sizeof(CvPoint)。
Storage为指向前面定义的内存存储器.
 
3、 ConvertScale

使用线性变换转换数组 

void cvConvertScale( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );

src 

输入数组. 

dst 

输出数组 

scale 

比例因子. 

shift 

该加数被加到输入数组元素按比例缩放后得到的元素上 

函数 cvConvertScale 有多个不同的目的因此就有多个同义函数(如上面的#define所示)。该函数首先对输入数组的

元素进行比例缩放,然后将shift加到比例缩放后得到的各元素上,即: dst(I)=src(I)*scale + (shift,shift,...),最后可

选的类型转换将结果拷贝到输出数组。 


多通道的数组对各个通道是独立处理的。 

类型转换主要用舍入和溢出截断来完成。也就是如果缩放+转换后的结果值不能用输出数组元素类型值精确表达,就

设置成在输出数组数据轴上最接近该数的值。 


如果 scale=1, shift=0 就不会进行比例缩放. 这是一个特殊的优化,相当于该函数的同义函数名:cvConvert

如果原来数组和输出数组的类型相同,这是另一种特殊情形,可以被用于比例缩放和平移矩阵或图像,此时相当于该

函数的同义函数名:cvScale。

4、UpdateMotionHistory

函数形式

void cvUpdateMotionHistory( const CvArr* silhouette, CvArr* mhi, double timestamp, double duration );

参数

  • silhouette
  • 影像 mask,运动发生地方具有非零象素
  • mhi
  • 运动历史图像(单通道, 32-比特 浮点数),为本函数所更新
  • timestamp
  • 当前时间,毫秒或其它单位
  • duration
  • 运动跟踪的最大持续时间,用 timestamp 一样的时间单位

说明

函数 cvUpdateMotionHistory 用下面方式更新运动历史图像:
mhi(x,y)=timestamp if silhouette(x,y)!=0 0 if silhouette(x,y)=0 and mhi(x,y)<timestamp-duration mhi(x,y) otherwise
也就是,MHI(motion history image) 中在运动发生的象素点被设置为当前时间戳,而运动发生较久的象素点被清除。
 
5、OpenCv中改变图像尺寸
首先初始目标图像尺寸:

方法一:IplImage*  dst= cvCreateImage( cvSize((size.width & -2)/2, (size.height & -2)/2), 8, 1 );

分析:size.width & -2----size.width和-2做‘与’运算

从补码算起,我们知道计算机内存里面负数是以补码形式存储并参与运算的,那-2的补码是多少呢?在vc环境下,注意到cvsize结构体内成员变量是int型的,而vc里面int型是占4个字节的所以-2的补码是:

11111111 11111111 11111111 11111110

那么size.width & -2就是把最后一位width的最后一位置0,

下面分析为什么要把最后一位置为0

如果源图像的width为奇数,则通过和-2相与,最后一位设为0,相当于图像width减小了1,然后再除以2,刚好为源图像分配了一半的width

如果源图像的width为偶数,则通过和-2相与,该数值不变,然后除以2,也为源图像分配一半的width。

方法二:按比例缩放float scale = 0.723; //缩放倍数为0.723倍则定义:

CvSize dst_size;

dst_size.height = (int)(pSrc->height*scale);
dst_size.width = (int)(pSrc->width*scale);

IplImage* dst= cvCreateImage( dst_size,8, 1 );

方法三:按具体高宽 

CvSize dst_size;

dst_size.height = 120;
dst_size.width = 60;

IplImage* dst= cvCreateImage( dst_size,8, 1 ); 

然后具体实施缩放

cvResize(src,dst,CV_INTER_LINEAR );

插值方法:
CV_INTER_NN - 最近邻插值,
CV_INTER_LINEAR - 双线性插值 (缺省使用)
CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法..
CV_INTER_CUBIC - 立方插值.

你可能感兴趣的:(CvMemStorage、ConvertScale,cvConvert , cvScale 、UpdateMotionHistory)