手势识别hog和hsvWord下载.docx

上传人:b****6 文档编号:21593368 上传时间:2023-01-31 格式:DOCX 页数:25 大小:31.17KB
下载 相关 举报
手势识别hog和hsvWord下载.docx_第1页
第1页 / 共25页
手势识别hog和hsvWord下载.docx_第2页
第2页 / 共25页
手势识别hog和hsvWord下载.docx_第3页
第3页 / 共25页
手势识别hog和hsvWord下载.docx_第4页
第4页 / 共25页
手势识别hog和hsvWord下载.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

手势识别hog和hsvWord下载.docx

《手势识别hog和hsvWord下载.docx》由会员分享,可在线阅读,更多相关《手势识别hog和hsvWord下载.docx(25页珍藏版)》请在冰豆网上搜索。

手势识别hog和hsvWord下载.docx

doublegetWinSigma()const;

virtualvoidsetSVMDetector(constvector<

float>

&

_svmdetector);

virtualboolload(constString&

filename,constString&

objname=String());

virtualvoidsave(constString&

objname=String())const;

virtualvoidcompute(constMat&

img,

vector<

descriptors,

SizewinStride=Size(),Sizepadding=Size(),

constvector<

Point>

locations=vector<

())const;

virtualvoiddetect(constMat&

img,vector<

foundLocations,

doublehitThreshold=0,SizewinStride=Size(),

Sizepadding=Size(),

searchLocations=vector<

virtualvoiddetectMultiScale(constMat&

Rect>

Sizepadding=Size(),doublescale=1.05,

intgroupThreshold=2)const;

//Mat&

angleOfs,与后文Mat&

qangle不一致,怀疑是笔误,由于qangle与angleOfs有不同含义,尽量改过来

virtualvoidcomputeGradient(constMat&

img,Mat&

grad,Mat&

angleOfs,

SizepaddingTL=Size(),SizepaddingBR=Size())const;

staticvector<

getDefaultPeopleDetector();

SizewinSize;

//窗口大小

SizeblockSize;

//Block大小

SizeblockStride;

//block每次移动宽度包括水平和垂直两个方向

SizecellSize;

//Cell单元大小

intnbins;

//直方图bin数目

intderivAperture;

//不知道什么用

doublewinSigma;

//高斯函数的方差

inthistogramNormType;

//直方图归一化类型,具体见论文

doubleL2HysThreshold;

//L2Hys化中限制最大值为0.2

boolgammaCorrection;

//是否Gamma校正

svmDetector;

//检测算子

};

**********************************************************************************/

namespacecv

size_tHOGDescriptor:

getDescriptorSize()const

//检测数据的合理性

CV_Assert(blockSize.width%cellSize.width==0&

blockSize.height%cellSize.height==0);

CV_Assert((winSize.width-blockSize.width)%blockStride.width==0&

(winSize.height-blockSize.height)%blockStride.height==0);

//Descriptor的大小

return(size_t)nbins*

(blockSize.width/cellSize.width)*

(blockSize.height/cellSize.height)*

((winSize.width-blockSize.width)/blockStride.width+1)*

((winSize.height-blockSize.height)/blockStride.height+1);

//9*(16/8)*(16/8)*((64-16)/8+1)*((128-16)/8+1)=9*2*2*7*15=3780,实际上的检测算子为3781,多的1表示偏置

doubleHOGDescriptor:

getWinSigma()const

//winSigma默认为-1,然而有下式知,实际上为4;

否则自己选择参数

returnwinSigma>

=0?

winSigma:

(blockSize.width+blockSize.height)/8.;

boolHOGDescriptor:

checkDetectorSize()const

//size_t:

unsignedint

size_tdetectorSize=svmDetector.size(),descriptorSize=getDescriptorSize();

//三种情况任意一种为true则表达式为true,实际上是最后一种

returndetectorSize==0||

detectorSize==descriptorSize||

detectorSize==descriptorSize+1;

voidHOGDescriptor:

setSVMDetector(constvector<

_svmDetector)

svmDetector=_svmDetector;

CV_Assert(checkDetectorSize());

load(constString&

objname)

//XML/YML文件存储

FileStoragefs(filename,FileStorage:

READ);

//objname为空,!

1=0,选择fs.getFirstTopLevelNode();

否则为fs[objname]

//注意到FileStorage中[]重载了:

FileNodeoperator[](conststring&

nodename)(returnsthetop-levelnodebyname)

FileNodeobj=!

objname.empty()?

fs[objname]:

fs.getFirstTopLevelNode();

if(!

obj.isMap())

returnfalse;

FileNodeIteratorit=obj["

winSize"

].begin();

it>

>

winSize.width>

winSize.height;

it=obj["

blockSize"

blockSize.width>

blockSize.height;

blockStride"

blockStride.width>

blockStride.height;

cellSize"

cellSize.width>

cellSize.height;

obj["

nbins"

]>

nbins;

derivAperture"

derivAperture;

winSigma"

winSigma;

histogramNormType"

histogramNormType;

L2HysThreshold"

L2HysThreshold;

gammaCorrection"

gammaCorrection;

FileNodevecNode=obj["

SVMDetector"

];

if(vecNode.isSeq())

vecNode>

CV_Assert(checkDetectorSize());

returntrue;

save(constString&

objName)const

WRITE);

//空的对象名则取默认名,输出有一定格式,对象名后紧接{

fs<

<

(!

objName.empty()?

objName:

FileStorage:

getDefaultObjectName(filename))<

"

{"

;

//之后依次为:

<

winSize

blockSize

blockStride

cellSize

nbins

derivAperture

getWinSigma()

histogramNormType

L2HysThreshold

svmDetector.empty())

[:

"

svmDetector<

]"

//注意还要输出"

}"

//img:

原始图像

//grad:

记录每个像素所属bin对应的权重的矩阵,为幅值乘以权值

//这个权值是关键,也很复杂:

包括高斯权重,三次插值的权重,在本函数中先值考虑幅值和相邻bin间的插值权重

//qangle:

记录每个像素角度所属的bin序号的矩阵,均为2通道,为了线性插值

//paddingTL:

Top和Left扩充像素数

//paddingBR:

类似同上

//功能:

计算img经扩张后的图像中每个像素的梯度和角度

computeGradient(constMat&

qangle,

SizepaddingTL,SizepaddingBR)const

//先判断是否为单通道的灰度或者3通道的图像

CV_Assert(img.type()==CV_8U||img.type()==CV_8UC3);

//计算gradient的图的大小,由64*128==》112*160,则会产生5*7=35个窗口(windowstride:

8)

//每个窗口105个block,105*36=3780维特征向量

//paddingTL.width=16,paddingTL.height=24

Sizegradsize(img.cols+paddingTL.width+paddingBR.width,

img.rows+paddingTL.height+paddingBR.height);

//注意grad和qangle是2通道的矩阵,为3D-trilinear插值中的orientation维度,另两维为坐标x与y

grad.create(gradsize,CV_32FC2);

//<

magnitude*(1-alpha),magnitude*alpha>

qangle.create(gradsize,CV_8UC2);

//[0..nbins-1]-quantizedgradientorientation

//wholeSize为parentmatrix大小,不是扩展后gradsize的大小

//roiofs即为img在parentmatrix中的偏置

//对于正样本img=parentmatrix;

但对于负样本img是从parentimg中抽取的10个随机位置

//至于OpenCv具体是怎么操作,使得img和parentimg相联系,不是很了解

//wholeSize与roiofs仅在padding时有用,可以不管,就认为传入的img==parentimg,是否是从parentimg中取出无所谓

SizewholeSize;

Pointroiofs;

img.locateROI(wholeSize,roiofs);

inti,x,y;

intcn=img.channels();

//产生1行256列的向量,lut为列向量头地址

Mat_<

_lut(1,256);

constfloat*lut=&

_lut(0,0);

//gamma校正,作者的编程思路很有意思

//初看不知道这怎么会与图像的gamma校正有关系,压根img都没出现,看到后面大家会豁然开朗的

if(gammaCorrection)

for(i=0;

i<

256;

i++)

_lut(0,i)=std:

sqrt((float)i);

else

_lut(0,i)=(float)i;

//开辟空间存xmap和ymap,其中各占gradsize.width+2和gradsize.height+2空间

//+2是为了计算dx,dy时用[-1,0,1]算子,即使在扩充图像中,其边缘计算梯度时还是要再额外加一个像素的

//作者很喜欢直接用内存地址及之间的关系,初看是有点头大的

//另外再说说xmap与ymap的作用:

其引入是因为img图像需要扩充到gradsize大小

//如果我们计算img中位于(-5,-6)像素时,需要将基于img的(-5,-6)坐标,映射为基于grad和qangle的坐标(xmap,ymap)

AutoBuffer<

int>

mapbuf(gradsize.width+gradsize.height+4);

int*xmap=(int*)mapbuf+1;

int*ymap=xmap+gradsize.width+2;

//BORDER_REFLECT_101:

(左插值)gfedcb|abcdefgh(原始像素)|gfedcba(右插值),一种插值模式constintborderType=(int)BORDER_REFLECT_101;

//borderInterpolate函数完成两项操作,一是利用插值扩充img,二是返回x-paddingTL.width+roiofs.x映射后的坐标xmap

//例如,ximg=x(取0)-paddingTL.width(取24)+roiofs.x(取0)=-24==>

xmap[0]=0

//即img中x=-24,映射到grad中xmap=0,并且存在xmap[0]中,至于borderInterpolate的具体操作可以不必细究

for(x=-1;

x<

gradsize.width+1;

x++)

xmap[x]=borderInterpolate(x-paddingTL.width+roiofs.x,

wholeSize.width,borderType);

for(y=-1;

y<

gradsize.height+1;

y++)

ymap[y]=borderInterpolate(y-paddingTL.height+roiofs.y,

wholeSize.height,borderType);

//x-&

y-derivativesforthewholerow

//由于后面的循环是以行为单位,每次循环内存重复使用,所以只要记录一行的信息而不是整个矩阵

intwidth=gradsize.width;

_dbuf(width*4);

float*dbuf=_dbuf;

//注意到内存的连续性方便之后的编程

MatDx(1,width,CV_32F,dbuf);

MatDy(1,width,CV_32F,dbuf+width);

MatMag(1,width,CV_32F,dbuf+width*2);

MatAngle(1,width,CV_32F,dbuf+width*3);

int_nbins=nbins;

floatangleScale=(float)(_nbins/CV_PI);

//9/pi

for(y=0;

gradsize.height;

//指向每行的第一个元素,img.data为矩阵的第一个元素地址

constuchar*imgPtr=img.data+img.step*ymap[y];

constuchar*prevPtr=img.data+img.step*ymap[y-1];

constuchar*nextPtr=img.data+img.step*ymap[y+1];

float*gradPtr=(float*)grad.ptr(y);

uchar*qanglePtr=(uchar*)qangle.ptr(y);

//1通道

if(cn==1)

for(x=0;

width;

intx1=xmap[x];

//imgPtr指向img第y行首元素,imgPtr[x]即表示第(x,y)像素,其亮度值位于0~255,对应lut[0]~lut[255]

//即若像素亮度为120,则对应lut[120],若有gamma校正,lut[120]=sqrt(120)

//由于补充了虚拟像素,即在imgPtr[-1]无法表示gradsize中-1位置元素,而需要有个转换

//imgPtr[-1-paddingTL.width+roiofs.x],即imgPtr[xmap[-1]],即gradsize中-1位置元素为img中xmap[-1]位置的元素

dbuf[x]=(float)(lut[imgPtr[xmap[x+1]]]-lut[imgPtr[xmap[x-1]]]);

//由于内存的连续性,隔width,即存Dy

dbuf[width+x]=(float)(lut[nextPtr[x1]]-lut[prevPtr[x1]]);

//3通道,3通道中取最大值

intx1=xmap[x]*3;

constuchar*p2=imgPtr+xmap[x+1]*3;

constuchar*p0=imgPtr+xmap[x-1]*3;

floatdx0,dy0,dx,dy,mag0,mag;

dx0=lut[p2[2]]-lut[p0[2]];

dy0=lut[nextPtr[x1+2]]-lut[prevPtr[x1+2]];

mag0=dx0*dx0+

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1