dayenglish的专栏

本文主要是根据分析一份matlab代码PHOG特征生成的demo得到的,作为总结便于以后使用。

if sum(sum(G))>100E = edge(G,'canny');[GradientX,GradientY] = gradient(double(G));GradientYY = gradient(GradientY);Gr = sqrt((GradientX.*GradientX)+(GradientY.*GradientY));index = GradientX == 0;GradientX(index) = 1e-5;YX = GradientY./GradientX;if angle == 180, A = ((atan(YX)+(pi/2))*180)/pi; endif angle == 360, A = ((atan2(GradientY,GradientX)+pi)*180)/pi; end[bh bv] = anna_binMatrix(A,E,Gr,angle,bin);elsebh = zeros(size(I,1),size(I,2));bv = zeros(size(I,1),size(I,2));end首先需要说明的是G是一幅灰度图,将灰度图看做矩阵进行统计,看看是否有足够的像素产生梯度信息,如果小于100的话,表明整个图像接近于是一幅完全的黑色图像。经过上面的比较之后,再对图像进行canny轮廓处理,得到的图像为0-1二值图像(至于其用处在后面介绍)。紧跟其后是对整个图像求梯度,由于梯度实际上是一个在X或者Y方向上的方向向量,所以后面的GradientY./GradientX就相当于求得某一个像素点处的方向向量(tan=sin/cos)。不过由于GradientX可能等于0,所以在此之前,需要对GradientX做一个调整,将等于0的调整为一个较小的值。由于atan返回的范围是-pi/2到pi/2,所以需要增加一个pi/2作为调整,然后将弧度转化为角度,而下面的atan2函数则适用于当角度为360的时候,实现功能和上面的atan很相似。function [bm bv] = anna_BinMatrix(A,E,G,angle,bin)[contorns,n] = bwlabel(E); X = size(E,2);Y = size(E,1);bm = zeros(Y,X);bv = zeros(Y,X);nAngle = angle/bin;for i=1:n[posY,posX] = find(contorns==i);for j=1:size(posY,1)pos_x = posX(j,1);pos_y = posY(j,1);b = ceil(A(pos_y,pos_x)/nAngle);if b==0, bin= 1; endif G(pos_y,pos_x)>0bm(pos_y,pos_x) = b;bv(pos_y,pos_x) = G(pos_y,pos_x);endendendbwlabel函数实现将连通域关联起来,并且将所有的连通域进行计数存放到第二个返回值中,第一个返回值是一个和图像一样大小的矩阵,这个矩阵中的第一个连通域填充1,第二个连通域填充2,以此类推。然后利用角度计算每一个直方图中的bin的跨度。利用之前计算出来的角度,,得出相应位置上的角度属于直方图的哪一个bin,并且在相应的位置存放角度值。bh_roi = bh(roi(1,1):roi(2,1),roi(3,1):roi(4,1));bv_roi = bv(roi(1,1):roi(2,1),roi(3,1):roi(4,1));p = anna_phogDescriptor(bh_roi,bv_roi,L,bin);function p = anna_PhogDescriptor(bh,bv,L,bin)p = [];%level 0for b=1:binind = bh==b;p = [p;sum(bv(ind))];endcella = 1;for l=1:Lx = fix(size(bh,2)/(2^l));y = fix(size(bh,1)/(2^l));xx=0;yy=0;while xx+x<=size(bh,2)while yy +y <=size(bh,1)bh_cella = [];bv_cella = [];bh_cella = bh(yy+1:yy+y,xx+1:xx+x);bv_cella = bv(yy+1:yy+y,xx+1:xx+x);for b=1:binind = bh_cella==b;p = [p;sum(bv_cella(ind))];endyy = yy+y;endcella = cella+1;yy = 0;xx = xx+x;endendif sum(p)~=0p = p/sum(p);end经过之前的代码已经生成了梯度方向了,只需要将这些梯度方向经过统计之后就可以得到一个HOG了。上面的第一个循环就是根据bin的个数统计第一层的直方图。而第二个循环则是根据图像金字塔得到局部的HOG特征,最后进行归一化。

上面是一个很简单的HOG的实现,当然和DPM中的HOG特征不可同日而语,不过对于理解HOG的计算以及生成还是很有帮助的。完整的代码可以到我的资源也下载

吃水不忘挖井人。

dayenglish的专栏

相关文章:

你感兴趣的文章:

标签云: