在作镜头检测以前,为方便起见,咱们先将一个视频短片提取出必定数量的图像序列。 算法
%%%%%提取图片序列%%%%%%%
video=mmreader('test.avi','Tag','Reader');
NOF=video.NumberOfFrames;
Img_diff=zeros(NOF-1,1);
mkdir([cd,'/images']);
directory=[cd,'/images/'];
for i=1:NOF
Img_I=read(video,i);
imwrite(Img_I,[directory,[num2str(i) '.jpg'];]);
end; ide
镜头边缘检测算法要作的是检测出一段视频片断中发生镜头切换的图像帧。通常在同一个镜头中,相邻的图像帧是类似的,因此能够经过检测相邻图像帧特征的突变来实现。如下是经典的几种算法。这些算法其实都离不开重要的两点,怎么定义图像的特征,怎么断定类似。 函数
绝对帧间差法:比较相邻图像帧像素的亮度和之差,当大于某个阈值时,则断定发生突变。这种算法阈值的选取会影响准确度。而对于阈值的肯定,应该还有改进的空间,此处简单的取全局平均值的1.1倍为阈值。 测试
for i=1:NOF-1
img_i=imread(strcat('images\',imglist(i).name));
img_i_plus=imread(strcat('images\',imglist(i+1).name));
img_diff(i)=norm(double(img_i(:,:,1)-img_i_plus(:,:,1)))+norm(double(img_i(:,:,2)-img_i_plus(:,:,2)))+norm(double(img_i(:,:,3)-img_i_plus(:,:,3)));
end;
Threshold=mean(img_diff)*1.1;
for i=2:NOF-2
if(img_diff(i)>img_diff(i-1)&&img_diff(i)>img_diff(i+1)&&img_diff(i)>Threshold)
fprintf('%d\n',i);
end;
end; spa
颜色直方图法:这种算法以图像的颜色直方图为图像特征,用直方图的交来衡量图片间的类似度。当类似度低于某个阈值时,则断定为突变。 orm
其实类似度的定义也很灵活,这里也只是提供了一个思路。 视频
clc;clear;clf;
d=dir('images');
NOF=max(size(d)-2);
img_diff=zeros(NOF-1,1);
imglist=d(3:NOF+2);
Threshold=0.45;
for i=1:NOF-1
img_i=imread(strcat('images\',imglist(i).name));
img_i_plus=imread(strcat('images\',imglist(i+1).name));
Hist1=imhist(rgb2gray(img_i));
Hist2=imhist(rgb2gray(img_i_plus));
S=min(Hist1(1),Hist2(1));
for j=2:length(Hist1)
S=S+min(Hist1(j),Hist2(j));
end;
H=sum(Hist1);
img_diff(i)=S/H;
end;
for i=1:length(img_diff)
if(img_diff(i)<Threshold)
fprintf('%d\n',i);
end;
end; htm
感知哈希法:感知哈希法是用于类似图片搜索的一种快速算法。因为镜头检测算法所面向的对象也是成千上百帧的图像帧,因此我尝试将这种算法用于镜头检测。 对象
clc;clear;clf;
d=dir('images');
NOF=max(size(d)-2);;
imglist=d(3:NOF+2);
Threshold=6;
count=zeros(NOF-1,1);
for i=1:NOF-1
img_i=imread(strcat('images\',imglist(i).name));
img_i_plus=imread(strcat('images\',imglist(i+1).name));
imbw_i=im2bw(rgb2gray(imresize(img_i,[8,8])));
imbw_i_plus=im2bw(rgb2gray(imresize(img_i_plus,[8,8])));
for j=1:8
for k=1:8
if(imbw_i(j,k)~=imbw_i_plus(j,k))
count(i)=count(i)+1;
end;
end;
end;
end;
for i=1:NOF-2
if(count(i)>Threshold)
fprintf('%d\n',i);
end;
end; 图片
clc;clear;clf; d=dir('images'); NOF=max(size(d)-2); img_sim=zeros(NOF-1,1); imglist=d(3:NOF+2); for i=1:NOF-1 img_i=imread(strcat('images\',imglist(i).name)); img_i_plus=imread(strcat('images\',imglist(i+1).name)); img_sim(i)=corr2(img_i(:,:,1),img_i_plus(:,:,1))+corr2(img_i(:,:,2),img_i_plus(:,:,2))+corr2(img_i(:,:,3),img_i_plus(:,:,3)); img_sim(i)=img_sim(i)/3; end; Threshold=0.05; for i=1:length(img_sim) if(img_sim(i)<Threshold) fprintf('%d\n',i); end; end;
通过测试检验,发现以上的算法虽然能大体检测出一些镜头,可是准确率不是很理想,尤为是对渐变的镜头。总的来讲这几个算法都太粗糙了,究其缘由。一个是对于特征的定义太过单一,没法全美的反应图片的特征,另外对于类似度函数的定义或者阈值(能够考虑自适应的阈值)的肯定也有待改进。