几种简单常用的镜头边缘检测算法(matlab实现)

来源:互联网 发布:嵌入式算不算人工智能 编辑:程序博客网 时间:2024/05/02 01:48

在做镜头检测之前,为方便起见,我们先将一个视频短片提取出一定数量的图像序列。

%%%%%提取图片序列%%%%%%%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;

镜头边缘检测算法要做的是检测出一段视频片段中发生镜头切换的图像帧。一般在同一个镜头中,相邻的图像帧是相似的,所以可以通过检测相邻图像帧特征的突变来实现。以下是经典的几种算法。这些算法其实都离不开重要的两点,怎么定义图像的特征怎么判定相似

绝对帧间差法:比较相邻图像帧像素的亮度和之差,当大于某个阈值时,则判定发生突变。这种算法阈值的选取会影响准确度。而对于阈值的确定,应该还有改进的空间,此处简单的取全局平均值的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;

颜色直方图法:这种算法以图像的颜色直方图为图像特征,用直方图的交来衡量图片间的相似度。当相似度低于某个阈值时,则判定为突变。以下是直方图交的定义
其实相似度的定义也很灵活,这里也只是提供了一个思路。
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;
感知哈希法:感知哈希法是用于相似图片搜索的一种快速算法。由于镜头检测算法所面向的对象也是成千上百帧的图像帧,所以我尝试将这种算法用于镜头检测。
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;

经过测试检验,发现以上的算法虽然能大致检测出一些镜头,但是准确率不是很理想,尤其是对渐变的镜头。总的来说这几个算法都太粗糙了,究其原因。一个是对于特征的定义太过单一,无法全美的反应图片的特征,另外对于相似度函数的定义或者阈值(可以考虑自适应的阈值)的确定也有待改进。