基于聚类的关键帧提取法
会弹出这几幅关键帧的图像
程序中的基本思路:
1.以第一帧图像的 R,G,B 直方图为初始质心,获取第一幅图像的 R,G,B 三幅
图像的直方图,为 1*256 的矩阵.
2.对比第二帧与第一个聚类质心(开始为第一帧的 RGB 直方图),若第二帧类似
于第一帧(这里比较两个图像的 RGB 三种质心的距离,根据预先设定的阈值进行
判断),第二帧加入第一帧的聚类,同在新加入的图像与初试质心的基础上,生
成新的质心,作为与新帧比较的基础。若不类似,则生成新的聚类。下次比较时
新的帧将会与所有的聚类的质心进行比较,选择归属的聚类或者生成新的聚类。
如此往复,将会生成几个聚类,同时每个帧都会有所归属。
关键帧提取的第一步应该是进行镜头切割。镜头分割,已经写过几种简单
的办法了,见 CSDN 上查找一下
https://blog.csdn.net/weixin_43384257/article/details/83538288。镜头分
割以后,就要对每一个镜头进行关键帧提取,每个镜头都会提取出来几个关键帧。
关键帧提取的代码如下:是在 matlab 下运行的。
filenames=dir('D:\Documents\MATLAB\K_means_tiqu\airplane/*.jpg');%这
个是一个镜头所有帧的存储路径
%file_name = fly-1;
num=size(filenames,1);
key=zeros(1,num);
0
cluster=zeros(1,num);
clusterCount=zeros(1,num);
数
count=0;
%[0,0,0,0,0,0,0,0,0,0,0,0,....0,0,0,0]
[0,0,0,0,0,0,0,0,0,0,0,0,....0,0,0,0]
[0,0,0,0,0,0,0,0,0,0,0,0,....0,0,0,0]
%输出 filenames 中文件图片的个数
%一行,num 列都是
%各聚类有的帧
%聚类的个数
0.95 更好
%阈值越大帧越多
%threshold=0.75;
%airplane 这个视频阈值设为 0.93 比较合适
%0.93
%*********************************************阈值自己设定,看是多少时
效果最好******************************************************%
threshold=0.93;
第一帧图片 256 个初
centrodR=zeros(num,256);
始化全部为 0,第二帧也是,其余帧都是 %%%后面相似度大加入一帧后会对其
进行调整
centrodG=zeros(num,256);
centrodB=zeros(num,256);
%聚类质心 G 的直方图
%聚类质心 B 的直方图
%聚类质心 R 的直方图
%阈值
if num==0
error('Sorry, there is no pictures in images folder!');
else
%令首帧形成第一个聚类
img=imread(strcat('airplane/',filenames(1).name));
count=count+1;
[preCountR,x]=imhist(img(:,:,1));
%产生第一个聚类
%red histogram
得到红
色的直方图一共 256 个数值,每个数值有多少作为直方图的高度
[preCountG,x]=imhist(img(:,:,2));
[preCountB,x]=imhist(img(:,:,3));
%green histogram
%blue histogram
cluster(1)=1;
%设定第一个聚类选取的关键帧初始为首
帧 cluster 变为了(1,0,0,0,0,......,0,0,0)cluster(1)是改变了第一个
元素
clusterCount(1)=clusterCount(1)+1;%clusterCount(1)为 0,加 1,变
为 1,最终 clusterCount(1)为[1,0,0,0,.....,0,0,0]
centrodR(1,:)=preCountR; % centrodR 本来是 num(帧个数)行,256
列,全部为 0.。现在第一行为第一帧的红色直方图各个数值的高度
centrodG(1,:)=preCountG;
centrodB(1,:)=preCountB;
for k=2:num
img=imread(strcat('airplane/',filenames(k).name));
%循
环读取每一帧,首先是第 2 帧
[tmpCountR,x]=imhist(img(:,:,1));
%red histogram 得
到红色分量直方图 第二幅图片的红色直方图
[tmpCountG,x]=imhist(img(:,:,2));
[tmpCountB,x]=imhist(img(:,:,3));
%green histogram
%blue histogram
clusterGroupId=1;
maxSimilar=0;
%新定义的一个变量 clusterGroupId 为 1
%新定义,相似度
for clusterCountI=1:count
%目前 count 为
定义新变量 clusterCountI
1
个聚类
I 来确定这一帧归属于第一个聚类还是第二
sR=0;
sG=0;
sB=0;
%运用颜色直方图法的差别函数
for j=1:256
+sR;%,j 从 1 到 256,第一帧中 R 的所有值 256 个亮度 以及第二帧的红色直
方图所有高度值 进行比较选最小的
sR=min(centrodR(clusterCountI,j),tmpCountR(j))
+sG;
+sB;
sG=min(centrodG(clusterCountI,j),tmpCountG(j))
sB=min(centrodB(clusterCountI,j),tmpCountB(j))
end
dR=sR/sum(tmpCountR);
dG=sG/sum(tmpCountG);
dB=sB/sum(tmpCountB);
%YUV,persons are sensitive to Y
d=0.30*dR+0.59*dG+0.11*dB;
%运用颜色直方图法的差
别函数 定义了 d 差别函数
if d>maxSimilar
clusterGroupId=clusterCountI;
maxSimilar=d;
end
end
if maxSimilar>threshold
%相似度大,与该聚类质心距离小
%加入该聚类,并调整质心
for ii=1:256
centrodR(clusterGroupId,ii)=centrodR(clusterG
roupId,ii)*clusterCount(clusterGroupId)/(clusterCount(clusterGroupId)
+1)+tmpCountR(ii)*1.0/(clusterCount(clusterGroupId)+1);
centrodG(clusterGroupId,ii)=centrodG(clusterG
roupId,ii)*clusterCount(clusterGroupId)/(clusterCount(clusterGroupId)
+1)+tmpCountG(ii)*1.0/(clusterCount(clusterGroupId)+1);
centrodB(clusterGroupId,ii)=centrodB(clusterG
roupId,ii)*clusterCount(clusterGroupId)/(clusterCount(clusterGroupId)
+1)+tmpCountB(ii)*1.0/(clusterCount(clusterGroupId)+1);
end
clusterCount(clusterGroupId)=clusterCount(clusterGr
oupId)+1;
cluster(k)=clusterGroupId;
%第 k 帧在第
clusterGroupId 个聚类里面
聚类或者第二个聚类
else
cluster(3)等于 1 或者 2,,也就是属于第一个
%形成新的聚类,增加一个聚类质心
count=count+1;
clusterCount(count)=clusterCount(count)+1;
centrodR(count,:)=tmpCountR;
centrodG(count,:)=tmpCountG;
centrodB(count,:)=tmpCountB;
面
否则 cluster(k)就在新建的聚类中
cluster(k)=count;
%第 k 帧在第 count 个聚类里
end
end
%至此,所有帧都划进相应的聚类,一共有 count 个聚类,第 k 帧在第
cluster(k)聚类中
%现欲取出每个聚类中离质心距离最近,即相似度最大的作为该聚类的关
键帧
maxSimilarity=zeros(1,count);
frame=zeros(1,count);
for i=1:num
sR=0;
sG=0;
sB=0;
%运用颜色直方图法的差别函数
for j=1:256
一帧和聚类质心进行比较,取最小值
sR=min(centrodR(cluster(i),j),tmpCountR(j))+sR;%每
sG=min(centrodG(cluster(i),j),tmpCountG(j))+sG;
sB=min(centrodB(cluster(i),j),tmpCountB(j))+sB;
end
dR=sR/sum(tmpCountR);
dG=sG/sum(tmpCountG);
dB=sB/sum(tmpCountB);
%YUV,persons are sensitive to Y
d=0.30*dR+0.59*dG+0.11*dB;
if d>maxSimilarity(cluster(i))
maxSimilarity(cluster(i))=d;
frame(cluster(i))=i;
end
end
for j=1:count
key(frame(j))=1;
figure(j);
imshow(strcat('airplane/',filenames(frame(j)).name));
end
end
keyFrameIndexes=find(key)