matlab 反向投影图,matlab练习程序(直方图反向投影) | 学步园

做meanshift物体跟踪的时候中间有一步叫做直方图反向投影,所以我就先实现了这样一个步骤。

直方图反向投影说白了就是模板匹配,给定一个较小的目标模板,然后再逐个遍历原图像和模板图像相同的图像块的,对比图像块和模板的直方图,然后把比较结果存入一个新的图像中,新图像中的全局极值就是模板在原图像中所在的位置。这里主要麻烦的是怎么比较两个图像块的直方图,Opencv中实现了5种对比的方法,所以我在这里也对应的实现了5种方法。

5种方法分别是correl(相关)、chisqr(卡方)、intersect(相交)、bhattacharyya(名字很长--!!)、emd(earth mover's distance)。

下面是这5种方法的公式,H1是第一个图像块的直方图序列,H2是第二的图像块的直方图序列:

相关法:

e59504dbcf32e611fabb467129a472d3.png

其中:

d659b7e6b12d987b320aa344e3d8e88b.png

卡方法:

b258ced2838ab9b1827d0bfbcc1e41bf.png

相交法:

bf95c7589993e64c28bb246979683012.png

bhattacharyya:

9f0fe794d4b0c5cf7289ba20b71dd76e.png

emd:

2b3354ea595972ef53f6e584cc49b892.gif

前4种方法比较简单,emd就比较麻烦了,下面是我自己的理解。这个

下面是代码:

main.m

close all;

clear all;

clc;

img=imread('lena.jpg');

imshow(img);

[m n]=size(img);

w=imcrop(); %这里把要裁剪的图像框出来

[H W]=size(w);

hist1=histcount(w);

HH=floor(H/2);

WW=floor(W/2);

imgn=zeros(m+2*HH+1,n+2*WW+1);

imgn(HH+1:m+HH,WW+1:n+WW)=img;

imgn(1:HH,WW+1:n+WW)=img(1:HH,1:n);

imgn(1:m+HH,n+WW+1:n+2*WW+1)=imgn(1:m+HH,n:n+WW);

imgn(m+HH+1:m+2*HH+1,WW+1:n+2*WW+1)=imgn(m:m+HH,WW+1:n+2*WW+1);

imgn(1:m+2*HH+1,1:WW)=imgn(1:m+2*HH+1,WW+1:2*WW);

re1=imgn;

re2=imgn;

re3=imgn;

re4=imgn;

re5=imgn;for i=HH+1:m+HHfor j=WW+1:n+WW

s=imgn(i-HH:i+HH,j-WW:j+WW);

hist2=histcount(s);

re1(i,j)=correl(hist1,hist2); %相关法

re2(i,j)=chisqr(hist1,hist2); %卡方法

re3(i,j)=intersect(hist1,hist2); %相交法

re4(i,j)=bhattacharyya(hist1,hist2); %名字很长的法

re5(i,j)=emd(hist1,hist2); %由于没有优化,速度实在太慢了,至少运行一晚上,慎用!!end

endfigure;

re1=re1(HH+1:m+HH,WW+1:n+WW);

imshow(mat2gray(re1));

figure;

re2=re2(HH+1:m+HH,WW+1:n+WW);

imshow(mat2gray(re2));

figure;

re3=re3(HH+1:m+HH,WW+1:n+WW);

imshow(mat2gray(re3));

figure;

re4=re4(HH+1:m+HH,WW+1:n+WW);

imshow(mat2gray(re4));

figure;

re5=re5(HH+1:m+HH,WW+1:n+WW);

imshow(mat2gray(re5));

histcount.m 统计直方图

function hist=histcount(w)

[H W]=size(w);

w=uint8(w);

hist=zeros(1,256);for i=1:Hfor j=1:W

hist(w(i,j)+1)=hist(w(i,j)+1)+1;end

endhist=hist/(H*W);end

correl.m 相关法

function d=correl(H1,H2)

d=sum(H1-mean(H1).*(H2-mean(H2)))/sqrt(sum((H1-mean(H1)).^2)*sum((H2-mean(H2)).^2));end

chisqr.m 卡方法

function d=chisqr(H1,H2)

d=sum(((H1-H2).^2)/(H1+H2));end

intersect.m 相交法

function d=intersect(H1,H2)

d=sum(min(H1,H2));end

bhattacharyya.m

function d=bhattacharyya(H1,H2)

d=sqrt(1-sum(sqrt(H1.*H2))/sqrt(sum(H1)*sum(H2)));end

emd.m 这里没优化,慎用!

function re=emd(H1,H2)

m=length(H1);

n=length(H2);

f=zeros(m,n);

d=zeros(m,n);for i=1:mfor j=1:nif i==j

d(i,j)=0;end

if j>i

d(i,j)=j-i;end

if j

d(i,j)=i-j;endf(i,j)=min(sum(H1(1:i)),sum(H2(1:j)));end

end

for i=m:-1:2f(:,i)=f(:,i)-f(:,i-1);end

for j=n:-1:2f(j,:)=f(j,:)-f(j-1,:);endre=(sum(sum(f.*d)))/sum(sum(f));end

下面是运行效果:

5e265b5082063c3f4fa5a73871735105.png原图

b13fc9bedfae7fcb8015c66547f1c7fb.png使用的模板,就是lena的右眼。

7b41ac24af172430540a5d429b122f4f.png相关法

9adf6219871d240fff4c2c02732dab15.png卡方法

4249a3426ac2d1ec6eae29f2d5a360e6.png相交法

c7555ab0c9fe8b0d29ed9b853e55d5a7.pngbhattacharyya法

fef595f0af765eaa5a09b3a83fa82319.pngemd法

emd时间最长,效果还不错。卡方法最快,效果最不好。相交法和bhattacharyya效果都挺不错的,时间也不算慢。

参考:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值