Hog算法在图像处理中,应用十分广泛,但是其计算速度比较慢,时间代价较大。hog算法现把项目中,自己写的优化加速后的代码贴出来。具体Hog的原理就不细说了,这个文章到处都有,并不复杂。(这个并不是标准的HOG算法,简化版,请注意,谢谢!)
代码:
代码主要分三部分,1>计算梯度,Bin;2>梯度累加;3>计算距离
<pre name="code" class="cpp"><span style="font-size:18px;">/*函数名:calGradBin
功 能:计算图像梯度和Bin
参 数:imagegray:灰度图像一维指针
height: 图像高度,也就是行数
width: 图像宽度,也就是列数
grad: 图像梯度,一维指针
ImageBin: 图像Bin,一维指针
作 者:adrianhust@gmail.com
修改日期:2014.5.26
*/
void calGradBin(unsigned char *imagegray,int height,int width,double *grad,unsigned char *ImageBin)
{
unsigned char pxl,pxr,pyu,pyd,flagx=0,flagy=0,gradx,grady;
int i,j;
for (i=1;i<height-1;i++)
{
for (j=1;j<width-1;j++)
{
pxl=imagegray[i*width+j-1];
pxr=imagegray[i*width+j+1];
pyu=imagegray[(i-1)*width+j];
pyd=imagegray[(i+1)*width+j];
if (pxl==pxr || pyu==pyd) //有一个方向梯度为0,方向即为0,梯度幅值也为0;
{
continue;
}
flagx=0,flagy=0;
if(pxl>pxr)
{
gradx=pxl-pxr;
}
else
{
gradx=pxr-pxl;
flagx=1;//正
}
if(pyu>pyd)
{
grady=pyu-pyd;
flagy=1;
}
else
{
grady=pyd-pyu;//正
}
if (flagx+flagy==1)//同时为正或同时为负
{
ImageBin[i*width+j]=2-BinNum[gradx-1][grady-1];
grad[i*width+j]=Mag[gradx-1][grady-1];
}
else
{
ImageBin[i*width+j]=BinNum[gradx-1][grady-1];
grad[i*width+j]=Mag[gradx-1][grady-1];
}
}
}
}
/*函数名:HogMap
功 能:计算图像Hog特征
参 数:ImageBin: 图像Bin数,一维指针
height: 图像高度,也就是行数
width: 图像宽度,也就是列数
grad: 图像梯度,一维指针
Hog: 图像Hog特征,一维指针
HeightHog:Hog特征高度
widthHog: Hog特征宽度
作 者:adrianhust@gmail.com
修改日期:2014.5.26
*/
void HogMap(unsigned char *ImageBin,double *grad,int height,int width,int bin,double *Hog,int HeightHog,int WidthHog)
{
int step=8,i,j,k,l;
int NumofCellinRow,NumofCellinCol,WidthofHog;
int CoordinateHog,CoordinateBinMag;
double tempsum;
NumofCellinRow=height>>3;
NumofCellinCol=width>>3;
WidthofHog=NumofCellinCol*bin;
HeightHog=NumofCellinRow;
WidthHog =WidthofHog;
for (i=0;i<NumofCellinRow;i+=1)
{
for (j=0;j<NumofCellinCol;j+=1)
{
CoordinateHog =i*WidthofHog+j*bin;
CoordinateBinMag =i*width*8+j*8;
tempsum=0.0000001;
for (k=0;k<8;k+=1)
{
for (l=0;l<8;l+=1)
{
Hog[CoordinateHog+ImageBin[CoordinateBinMag+k*width+l]] += grad[CoordinateBinMag+k*width+l];
}
}
tempsum+=Hog[CoordinateHog]+Hog[CoordinateHog+1]+Hog[CoordinateHog+2];
Hog[CoordinateHog]=Hog[CoordinateHog]/tempsum;
Hog[CoordinateHog+1]=Hog[CoordinateHog+1]/tempsum;
Hog[CoordinateHog+2]=Hog[CoordinateHog+2]/tempsum;
}
}
}
//I1为大图,I2为小图
/*函数名:Match
功 能:计算图像Hog特征匹配位置
参 数:I1: 大图指针
r1: 图像高度,也就是行数
c1: 图像宽度,也就是列数
I2: 小图指针
r1: 图像高度,也就是行数
c1: 图像宽度,也就是列数
x : 匹配点坐标,为列坐标
y : 匹配点坐标,为行坐标
作 者:adrianhust@gmail.com
修改日期:2014.5.26
*/
void Match(unsigned char *I1,int r1,int c1,unsigned char *I2,int r2,int c2,int *x,int *y)
{
unsigned char *I1Bin,*I2Bin;
double *I1Grad,*I2Grad,*I1Hog,*I2Hog;
double d,Min=1<<30;;
int i,j,itmp,jtmp;
int bin=3;
int I1NumofCellinRow=r1>>3;
int I1NumofCellinCol=c1>>3;
int I2NumofCellinRow=r2>>3;
int I2NumofCellinCol=c2>>3;
I1Bin =(unsigned char *)calloc(r1*c1,sizeof(unsigned char));
I1Grad=(double*)calloc(r1*c1,sizeof(double));
calGradBin(I1,r1,c1,I1Grad,I1Bin);
free(I1);
I1=NULL;
I1Hog=(double*)calloc(I1NumofCellinRow*I1NumofCellinCol*bin,sizeof(double));
HogMap(I1Bin,I1Grad,r1,c1,3,I1Hog,I1NumofCellinRow,I1NumofCellinCol*bin);
free(I1Bin);
I1Bin=NULL;
free(I1Grad);
I1Grad=NULL;
I2Bin =(unsigned char *)calloc(r2*c2,sizeof(unsigned char));
I2Grad=(double*)calloc(r2*c2,sizeof(double));
calGradBin(I2,r2,c2,I2Grad,I2Bin);
free(I2);
I2=NULL;
I2Hog=(double*)calloc(I2NumofCellinRow*I2NumofCellinCol*bin,sizeof(double));
HogMap(I2Bin,I2Grad,r2,c2,3,I2Hog,I2NumofCellinRow,I2NumofCellinCol*bin);
free(I2Bin);
I2Bin=NULL;
free(I2Grad);
I2Grad=NULL;
for (i=0;i<I1NumofCellinRow-I2NumofCellinRow;i+=1)
{
for (j=0;j<I1NumofCellinCol-I2NumofCellinCol;j+=1)
{
d=dist((I1Hog+i*I1NumofCellinCol*bin+j*bin),I2Hog,I1NumofCellinCol*bin,I2NumofCellinCol*bin,I2NumofCellinRow);
if (d<Min)
{
Min=d;
itmp=i;
jtmp=j;
}
}
}
*x=r1/2-itmp*8;
*y=c1/2-jtmp*8;
}
/*函数名:dist
功 能:计算两个向量距离
参 数:I: 向量指针
J: 向量指针
Iwidth: I向量宽度
Jwidth: J向量宽度
height: 向量高度,I,J相同
作 者:adrianhust@gmail.com
修改日期:2014.5.26
*/
double dist(double *I,double *J,int Iwidth,int Jwidth,int height)
{
int i,j;
double sum=0.0000001;
int coordinate1,coordinate2;
for (i=0;i<height;i+=1)
{
for (j=0;j<Jwidth;j+=1)
{
coordinate1=i*Iwidth+j;
coordinate2=i*Jwidth+j;
sum+=(*(I+coordinate1)-*(J+coordinate2))*(*(I+coordinate1)-*(J+coordinate2));
}
}
sum=sum/(Jwidth*height);
return sum;
}</span>
其中,Mag和BinNum为提前制作的表,用于查询加速,并未贴出。空间和速度都提升很大,480*384大图,320*256小图,去边25个像素,CCS速度大概170M时钟周期,空间不超过1M。hog算法不正之处,望指正。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-40331-1.html
亨利等等
不被发现达不到示威效果