聚类方法提取关键帧

上一篇文章中说到关键帧出现的顺序可能不对,现在解决这个问题。

加入了visit 使得帧循环时不用一个聚类一个聚类去比较,只和前一个聚类去比较。使得输出的帧是按顺序的。

filenames=dir('D:\Documents\MATLAB\K_means_tiqu\airplane/*.jpg');
%file_name = fly-1;
num=size(filenames,1);  %输出filenames中文件图片的个数
key=zeros(1,num);  %一行,num列都是0  [0,0,0,0,0,0,0,0,0,0,0,0,....0,0,0,0]
cluster=zeros(1,num);   %[0,0,0,0,0,0,0,0,0,0,0,0,....0,0,0,0]
clusterCount=zeros(1,num);  %各聚类有的帧数   [0,0,0,0,0,0,0,0,0,0,0,0,....0,0,0,0]
count=0;        %聚类的个数    

%threshold=0.75;  %阈值越大帧越多
%airplane这个视频阈值设为0.93比较合适   0.95更好
%********************************************************阈值**************************************************************%
threshold=0.91;  %阈值
centrodR=zeros(num,256);   %聚类质心R的直方图   第一帧图片256个初始化全部为0,第二帧也是,其余帧都是  %%%后面相似度大加入一帧后会对其进行调整
centrodG=zeros(num,256);   %聚类质心G的直方图
centrodB=zeros(num,256);   %聚类质心B的直方图

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));   %green histogram
    [preCountB,x]=imhist(img(:,:,3));   %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;
   
    visit = 1;
    for k=2:num
        img=imread(strcat('airplane/',filenames(k).name));  %循环读取每一帧,首先是第2帧
        [tmpCountR,x]=imhist(img(:,:,1));   %red histogram  得到红色分量直方图  第二幅图片的红色直方图
        [tmpCountG,x]=imhist(img(:,:,2));   %green histogram
        [tmpCountB,x]=imhist(img(:,:,3));   %blue histogram

        clusterGroupId=1;  %新定义的一个变量clusterGroupId为1
        maxSimilar=0;   %新定义,相似度
    
       
        for clusterCountI= visit:count          %目前 count为1   定义新变量clusterCountI  I来确定这一帧归属于第一个聚类还是第二个聚类
            sR=0;
            sG=0;
            sB=0;
            %运用颜色直方图法的差别函数
            for j=1:256
                sR=min(centrodR(clusterCountI,j),tmpCountR(j))+sR;%,j从1到256,第一帧中R的所有值256个亮度  以及第二帧的红色直方图所有高度值  进行比较选最小的
                sG=min(centrodG(clusterCountI,j),tmpCountG(j))+sG;
                sB=min(centrodB(clusterCountI,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;  %运用颜色直方图法的差别函数  定义了d  差别函数
            if d>maxSimilar
                clusterGroupId=clusterCountI;
                maxSimilar=d;
            end
        end
        
        if maxSimilar>threshold
            %相似度大,与该聚类质心距离小
            %加入该聚类,并调整质心
            for ii=1:256    
                centrodR(clusterGroupId,ii)=centrodR(clusterGroupId,ii)*clusterCount(clusterGroupId)/(clusterCount(clusterGroupId)+1)+tmpCountR(ii)*1.0/(clusterCount(clusterGroupId)+1);
                centrodG(clusterGroupId,ii)=centrodG(clusterGroupId,ii)*clusterCount(clusterGroupId)/(clusterCount(clusterGroupId)+1)+tmpCountG(ii)*1.0/(clusterCount(clusterGroupId)+1);
                centrodB(clusterGroupId,ii)=centrodB(clusterGroupId,ii)*clusterCount(clusterGroupId)/(clusterCount(clusterGroupId)+1)+tmpCountB(ii)*1.0/(clusterCount(clusterGroupId)+1);
            end
            clusterCount(clusterGroupId)=clusterCount(clusterGroupId)+1;
            cluster(k)=clusterGroupId;   %第k帧在第clusterGroupId个聚类里面   cluster(3)等于1或者2,,也就是属于第一个聚类或者第二个聚类
        else
            %形成新的聚类,增加一个聚类质心
            count=count+1;
             visit = visit+1;
            clusterCount(count)=clusterCount(count)+1;
            centrodR(count,:)=tmpCountR;
            centrodG(count,:)=tmpCountG;
            centrodB(count,:)=tmpCountB;
            cluster(k)=count;   %第k帧在第count个聚类里面   否则 cluster(k)就在新建的聚类中
        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)
 

产生新的问题:关键帧太多,造成冗余。

猜你喜欢

转载自blog.csdn.net/weixin_43384257/article/details/87889144