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 - 立方插值.

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#图像梯度 (注意都需要cv.convertScaleAbs将得到的有些负值取绝对值得到正数,并将数据转化到0-255之间,且sobel与Scarr算法中的数据位数都是32位浮点型的) import cv2 as cv import numpy as np def sobel_demo(image): #注意是32位float数据 grad_x = cv.Scharr(image, cv.CV_32F, 1, 0) grad_y = cv.Scharr(image, cv.CV_32F, 0, 1) #当用sobel算子不能很好的得到边缘的时候,就可以用Scharr算子,这是加强版的sobel算子,就可以得到 #原图像不是很明显的边缘了 # grad_x =cv.Sobel(image,cv.CV_32F,1,0) # grad_y =cv.Sobel(image,cv.CV_32F,0,1) gradx =cv.convertScaleAbs(grad_x) grady = cv.convertScaleAbs(grad_y) #cv.imshow("gradx",gradx) #cv.imshow("grady",grady) dst = cv.addWeighted(gradx,0.5,grady,0.5,0) cv.imshow("sobel_demo",dst) def lapalace_demo(image): #dst =cv.Laplacian(image,cv.CV_32F) #dst =cv.convertScaleAbs(dst) 会把dst变成单通道的8位的0-255的图像 #也可以用filter2D来做拉普拉斯算子 kernel = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]]) dst = cv.filter2D(image,cv.CV_32F,kernel) dst = cv.convertScaleAbs(dst) cv.imshow("lapalace",dst) src = cv.imread("E:/opencv/picture/step.jpg") cv.imshow("inital_window",src) #sobel_demo(src) lapalace_demo(src) cv.waitKey(0) cv.destroyAllWindows() 分析: 图像梯度可以把图像看成二维离散函数,图像梯度其实就是这个二维离散函数的求导。 一、 Sobel算子是普通一阶差分,是基于寻找梯度强度。拉普拉斯算子(二阶差分)是基于过零点检测。通过计算梯度,设置阀值,得到边缘图像。 def sobel_demo(image): #注意是32位float数据 grad_x = cv.Scharr(image, cv.CV_32F, 1, 0) grad_y = cv.Scharr(image, cv.CV_32F, 0, 1) #当用sobel算子不能很好的得到边缘的时候,就可以用Scharr算子,这是加强版的sobel算子,就可以得到 #原图像不是很明显的边缘了 # grad_x =cv.Sobel(image,cv.CV_32F,1,0) # grad_y =cv.Sobel(image,cv.CV_32F,0,1) gradx = cv.convertScaleAbs(grad_x) grady = cv.convertScaleAbs(grad_y) #cv.imshow("gradx",gradx) #cv.imshow("grady",grady) dst = cv.addWeighted(gradx,0.5,grady,0.5,0) cv.imshow("sobel_demo",dst) 1.Sobel算子用来计算图像灰度函数的近似梯度。Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。 2.Sobel具有平滑和微分的功效。即:Sobel算子先将图像横向或纵向平滑,然后再纵向或横向差分,得到的结果是平滑后的差分结果。 Ope

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值