DPM中的HOG源码的Matlab版重写-《小超教你写论文》系列第四部分第一篇
来源:互联网 发布:数据分析师职业收入 编辑:程序博客网 时间:2024/05/16 05:20
DPM中的HOG源码的Matlab版重写-《小超教你写论文》系列第四部分第一篇
《小超教你写论文》系列前三部分分别翻译了一篇文章;对文章中的公式进行了推导;介绍了作者使用的数据库。作为系列的第四部分,开始对原文中的想法进行实现。
前一段陷入了一点误区,一直在思考一个算法,总想把一切都弄得非常明白,耗费了很多时间。其实后来发现没有必要,我们的目的是写文章,而写文章需要我们实现自己的算法。如果我们的算法有从别人那里借鉴的部分,只需要将相同的部分弄明白就可以了,没必要完整彻底地理解别人的算法(ps:这里是指以写文章为目的的过程,并非所有科研过程)。
算法中,用到了DPM中的HOG特征,所以需要实现它。但在voc-release3.1的源码中,我发现HOG的实现是C语言版的,原大神可能是为了加快运算速度,但自己用起来不是很方便,所以就按照C语言写了一个Matlab版,几乎完全一样。其实,其中梯度方向分区的部分我曾经写过速度更快的方法,但为了与原版保持一致,没有做改变。
具体代码如下,包含了HOG特征求取和HOG特征图像化两个部分。
function feat = HOG(input,sbin)ticuu = [1.0000; 0.9397; 0.7660; 0.500; 0.1736; -0.1736; -0.5000; -0.7660; -0.9397]; vv = [0.0000; 0.3420; 0.6428; 0.8660; 0.9848; 0.9848; 0.8660; 0.6428; 0.3420]; %读入图片,若为灰度,将灰度转化为彩色input = imread('6.jpg');%figure,imshow(input);sbin = 8;%input = color(input);im = input;blocks = zeros(2,1);dims = zeros(3,1);[dims(1),dims(2),dims(3)] = size(input);blocks(1) = round(dims(1)/sbin);%行blocks(2) = round(dims(2)/sbin);%列hist = zeros(blocks(1),blocks(2),18);norm = zeros(blocks(1),blocks(2));out = zeros(3,1);out(1) = max(blocks(1)-2,0);%减2是为了方便一会儿每个block利用旁边四个block中进行归一化out(2) = max(blocks(2)-2,0);out(3) = 27+4;feat = zeros(out(1),out(2),out(3));%用来储存最后特征visible = zeros(2,1);visible(1) = blocks(1)*sbin;visible(2) = blocks(2)*sbin;%既然原代码是先列再行,我们也先列再行for x = 2:visible(2)-1 for y = 2:visible(1)-1 %第一通道 dy = im(y+1,x,1)-im(y-1,x,1); dx = im(y,x+1,1)-im(y,x-1,1); v = dy*dy+dx*dx; %第二通道 dy2 = im(y+1,x,2)-im(y-1,x,2); dx2 = im(y,x+1,2)-im(y,x-1,2); v2 = dy2*dy2+dx2*dx2; %第三通道 dy3 = im(y+1,x,3)-im(y-1,x,3); dx3 = im(y,x+1,3)-im(y,x-1,3); v3 = dy3*dy3+dx3*dx3; %选择最强的梯度 if (v2 > v) v = v2; dx = dx2; dy = dy2; end if (v3 > v) v = v3; dx = dx3; dy = dy3; end %对应到18个方向中的一个 best_dot = 0; best_o = 1; for o = 1:9 dot = uu(o)*dx + vv(o)*dy; if dot>best_dot best_dot = dot; best_o = o; else if -dot>best_dot best_dot = -dot; best_o = o+9; end end end %使用线性差值加到像素周围的四个直方图中 xp = (x-0.5)/sbin + 0.5; yp = (y-0.5)/sbin + 0.5; ixp = floor(xp); iyp = floor(yp); vx0 = xp-ixp; vy0 = yp-iyp; vx1 = 1.0-vx0; vy1 = 1.0-vy0; v = sqrt(double(v)); %左上角 if ixp >= 1 && iyp >= 1 hist(iyp,ixp,best_o) = hist(iyp,ixp,best_o)+vx1*vy1*v; end %右上角 if ixp < blocks(2) && iyp >= 1 hist(iyp,ixp+1,best_o) = hist(iyp,ixp+1,best_o)+vx0*vy1*v; end %左下角 if ixp >= 1 && iyp < blocks(1) hist(iyp+1,ixp,best_o) = hist(iyp+1,ixp,best_o)+vx1*vy0*v; end %右下角 if ixp < blocks(2) && iyp < blocks(1) hist(iyp+1,ixp+1,best_o) = hist(iyp+1,ixp+1,best_o)+vx0*vy0*v; end endend%通过计算梯度方向上的和计算每个block中的能量for o = 1:9 for x=1:blocks(2) for y=1:blocks(1) norm(y,x) = norm(y,x) + (hist(y,x,o)+hist(y,x,o+9))*(hist(y,x,o)+hist(y,x,o+9)); end endendeps = 0.0001;%计算特征for x = 1:out(2) for y = 1:out(1) %右下角 n1 = 1/sqrt(norm(y+1,x+1)+norm(y+2,x+1)+norm(y+1,x+2)+norm(y+2,x+2)+eps); %右边 n2 = 1/sqrt(norm(y,x+1)+norm(y+1,x+1)+norm(y,x+2)+norm(y+1,x+2)+eps); %下边 n3 = 1/sqrt(norm(y+1,x)+norm(y+2,x)+norm(y+1,x+1)+norm(y+2,x+1)+eps); %自己 n4 = 1/sqrt(norm(y,x)+norm(y+1,x)+norm(y,x+1)+norm(y+1,x+1)+eps); t1 = 0; t2 = 0; t3 = 0; t4 = 0; %对比度敏感特征 for o = 1:18 h1 = min(hist(y+1,x+1,o)*n1,0.2);%截短 h2 = min(hist(y+1,x+1,o)*n2,0.2); h3 = min(hist(y+1,x+1,o)*n3,0.2); h4 = min(hist(y+1,x+1,o)*n4,0.2); feat(y,x,o) = 0.5 * (h1+h2+h3+h4);%求和 t1 = t1+h1; t2 = t2+h2; t3 = t3+h3; t4 = t4+h4; end %对比度不敏感特征 for o = 1:9 sum = hist(y+1,x+1,o) + hist(y+1,x+1,o+9); h1 = min(sum*n1, 0.2); h2 = min(sum*n2, 0.2); h3 = min(sum*n3, 0.2); h4 = min(sum*n4, 0.2); feat(y,x,o+18) = 0.5 * (h1+h2+h3+h4); end %纹理特征 feat(y,x,28) = 0.2357*t1; feat(y,x,29) = 0.2357*t2; feat(y,x,30) = 0.2357*t3; feat(y,x,31) = 0.2357*t4; endend%%%%%%%%%下面开始视觉化的部分%%%%%%%%%%%%%%%%对应于原程序的HOGpicturebs = 20;w = feat(:,:,1:9);scale = max(max(w(:)),max(-w(:)));% 给每一个方向做一个“条纹沟”bim1 = zeros(bs, bs);bim1(:,round(bs/2):round(bs/2)+1) = 1;bim = zeros([size(bim1) 9]);%bim(:,:,1) = bim1;for i = 2:9, bim(:,:,i) = imrotate(bim1, -(i-1)*20, 'crop');end% 通过将权重化的条纹加起来做成正权重的图案s = size(w); w(w < 0) = 0; im = zeros(bs*s(1), bs*s(2));for i = 1:s(1), iis = (i-1)*bs+1:i*bs; for j = 1:s(2), jjs = (j-1)*bs+1:j*bs; for k = 1:9, im(iis,jjs) = im(iis,jjs) + bim(:,:,k) * w(i,j,k); end endendpos = im * 255/scale;% %通过将权重化的条纹加起来做成负权重的图案% w = -w;% s = size(w); % w(w < 0) = 0; % im = zeros(bs*s(1), bs*s(2));% for i = 1:s(1),% iis = (i-1)*bs+1:i*bs;% for j = 1:s(2),% jjs = (j-1)*bs+1:j*bs; % for k = 1:9,% im(iis,jjs) = im(iis,jjs) + bim(:,:,k) * w(i,j,k);% end% end% end% neg = im * 255/scale;% 将图像加起来画一下buff = 10;pos = padarray(pos, [buff buff], 128, 'both');%neg = padarray(neg, [buff buff], 128, 'both');%im = uint8([pos; neg]);im = uint8(pos);clf;imagesc(im); colormap gray;axis equal;axis off;toc
测试时所用的图像为
求得的HOG可视化以后为:
可以看到有很多竖线,说明竖直方向的HOG特征比较强,但总觉得有问题。将竖直方向的HOG特征分量置为零以后,即将可视化代码中的bim(:,:,1) = bim1;这句注销掉,
会得到下面的图像。
看着更合理一些吧。代码我是完全按照voc中的features.cc编写的,如果有谁发现有不一样的地方,请一定不吝赐教。下一篇应该会是latant-svm的matlab版本。
0 0
- DPM中的HOG源码的Matlab版重写-《小超教你写论文》系列第四部分第一篇
- 如何动笔写你的第一篇论文
- 关于HOG和DPM的论文和译文
- 《小超教你写论文》系列第四篇4.2-使用ACF算法进行行人检测
- 写第一篇论文(nash bargain)的坎坷历程
- 通过第一篇论文上手LaTeX,你可以的!
- 我的第一篇论文
- 第一篇论文的流程
- 我的第一篇论文
- 写论文第一天:熟悉MATLAB操作
- 【Apollo源码分析】系列的第四部分【decision】
- 《小超教你写论文》系列第二篇-公式推导
- xelatex生成一篇论文的各个部分
- 为什么现在开始写你的第一篇博客
- C++实现DPM/latentSVM --- 第一篇
- 2012第一篇,激励!要得到我想要的,乖乖写论文!
- 杂谈——如何开始写自己的第一篇论文
- 今天写了我的人生中的第一篇博客
- cvLoadImage函数使用方法
- UI 第一节复习 UIWindow UIView
- freemarker自定义标签报错(一)
- 编写高质量代码——“零星”总结(续2)
- 对于ios7扫描二维码功能的实现
- DPM中的HOG源码的Matlab版重写-《小超教你写论文》系列第四部分第一篇
- 易信公众平台开发从入门到精通之获取凭证利用SAE缓存
- Hbase 创建表 shell 命令
- 云计算的分类
- 华为OJ_2128_字符串加解密
- cocos2dX 之CCParticle
- 如何让搜索引擎了解您的主页
- 内联函数
- windows shell 相关